This is the mail archive of the cygwin-xfree@cygwin.com mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

proposing a different aproach for XwinClip (but need some help)


 Hi,

  I have implemented a different aproach about
copying clipboard contents between XFree86 and Windows based on
 the original xwinclip.
 It's less automatic but allows the user to control when to copy.
 There is a windows trayicon with a menu to copy from Windows
 or from X11. As it is possible to have several Xfree running
connected to different XClients (machines) there is submenu
to select which client you want to use.

 But i have a problem when copying from windows to X11
(only tested with Kde 2.2.1) the new selection added to the Klipper
is not "activated" (so no paste with mouse middle button )
and if i do a message loop for "selectionrequest"
events, it receives an infinite number of those events:
---
XLoop new event
xevent.xselectionrequest.property _QT_SELECTION
target type TARGETS 334

XLoop new event
xevent.xselectionrequest.property _QT_SELECTION
target type XA_STRING 31
...
---

The function that performs this is "CopyFromWindows"

Below is the code:

// Standard library headers
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
//
#include <dirent.h>


// X headers */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
//------------------------------------------------------------------


// Fixups to prevent collisions between Windows and X headers
#undef MINSHORT
#undef MAXSHORT

// Flags for Windows header options
#define NONAMELESSUNION
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

// Windows headers
#include <w32api/windows.h>
#include <w32api/windowsx.h>
#include <w32api/shellapi.h>

//-----------------------------------------------
#define MYWM_NOTIFYICON		(WM_APP+100)
#define IDM_EXIT                        1000
#define IDM_FROM                         100
#define IDM_TO                           200

#define ID_ICON_APP                       1
#define ID_ICON_TRAY                      4
#define MAX_DISPLAYS   9

//------------------------------------------------

#ifndef ARRAYSIZE
#define ARRAYSIZE(a)    (sizeof(a)/sizeof(a[0]))
#endif

// Application constants
#define WINDOW_CLASS		"XWinClip"
#define WINDOW_TITLE		"xwinclip"


// Global variables
BOOL DisplayIds[MAX_DISPLAYS] = {FALSE, };

//--------------------------------------------------------------------------
-------
//  MS-Windows Global Vars
HINSTANCE       ghInstance;
HINSTANCE       ghResInst;
HMENU           hPopupMnu;
HMENU           hmToWin;
HMENU           hmToX11;
HWND		hAppWnd;

// Function prototypes
HWND CreateMessagingWindow(void);
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam);
void DOStoUNIX (char *pszData, int iLength);
void UNIXtoDOS (unsigned char **ppszData, int iLength);
//---------


//--------------------------------------------------------------------------
-------
//--------------------------------------------------------------------------
-------
BOOL DoCopyFromX11(Display *pDisplay, Window iMyWindow, unsigned char
**ppszReturnData)
{
 Atom	 atomReturnType;
 Atom	 atomLocalProperty;
 Atom	 atomUTF8String;
 int		iReturnFormat;
 unsigned long	ulReturnItems, ulReturnBytesLeft;
 int		iReturn;
 BOOL GotIt;

  // Local property to hold pasted data
  atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False);
  if (atomLocalProperty == None)
  {
     MessageBox(hAppWnd, "Could not create CYGX_CUT_BUFFER atom",
"XWinClip", MB_OK);
     return FALSE;
  }

  iReturn = XConvertSelection (pDisplay, XA_PRIMARY, XA_STRING,
			       atomLocalProperty, iMyWindow, CurrentTime);
  if (iReturn == BadAtom || iReturn == BadWindow)
  {
	      printf ("From X11 - XConvertSelection () failed\n");
	      return FALSE;
  }

  GotIt = FALSE;
  // Loop for X events
  while (!GotIt)
  {
   XEvent xevent;
      // Block until the next X event
      XNextEvent (pDisplay, &xevent);
      //printf("XLoop new event\n");
      // Branch on the event type
      switch (xevent.type)
      {
      	case SelectionNotify:
                GotIt = TRUE;
                //printf("Getting Size of property of Window %d\n",
iMyWindow);
                // Retrieve the size of the stored data
                iReturn = XGetWindowProperty (pDisplay,	iMyWindow,
                			      atomLocalProperty,
                			      0,
                			      0, // Don't get data, just get size */
                			      False,
                			      AnyPropertyType,
                			      &atomReturnType,
                			      &iReturnFormat,
                			      &ulReturnItems,
                			      &ulReturnBytesLeft,
                			      ppszReturnData);
                if (iReturn != Success)
                {
                   MessageBox(hAppWnd, "From X11 - XGetWindowProperty ()
failed", "XWinClip", MB_OK);
                   return FALSE;
                }
                //printf("From X11 - returned data %d left %d\n",
ulReturnItems, ulReturnBytesLeft);

                if (ulReturnBytesLeft <= 0)
                {
                   MessageBox(hAppWnd, "XGetWindowProperty() returned 0
bytes", "XWinClip", MB_OK);
                   return FALSE;
                }
                // Request the selection data
                iReturn = XGetWindowProperty (pDisplay, iMyWindow,
                			      atomLocalProperty,
                			      0,
                			      ulReturnBytesLeft,
                			      False,
                			      AnyPropertyType,
                			      &atomReturnType,
                			      &iReturnFormat,
                			      &ulReturnItems,
                			      &ulReturnBytesLeft,
                			      ppszReturnData);
                if (iReturn != Success)
                {
                   MessageBox(hAppWnd, "SelectionNotify - XGetWindowProperty
() failed", "XWinClip", MB_OK);
                   return FALSE;
                }
                break;

        default:
                // ++ if GotIt = TRUE  (some kind of timeout);
                break;
      }
  }
  //printf("exiting XLoop\n");
  //printf("From X11 - returned data %s, %d\n", *ppszReturnData,
strlen(*ppszReturnData) );
  return TRUE;
}


//--------------------------------------------------------------------------
-------
//--------------------------------------------------------------------------
-------
BOOL DoPasteToWindows(char *pszReturnData)
{
 HGLOBAL  hGlobal;
 char	  *pszGlobalData;
 BOOL     result = TRUE;

  // Access the Windows clipboard
  if (!OpenClipboard (hAppWnd))
  {
     printf ("OpenClipboard () failed\n");
     return FALSE;
  }
  // Take ownership of the Window clipboard
  if (!EmptyClipboard ())
  {
     MessageBox(hAppWnd, "EmptyClipboard () failed", "XWinClip", MB_OK);
     result = FALSE;
  }
  // Allocate global memory for the X clipboard data
  if (result)
      hGlobal = GlobalAlloc (GMEM_MOVEABLE, strlen(pszReturnData) + 1);
  result = !(hGlobal == NULL);

  // Obtain a pointer to the global memory
  if (result)
       pszGlobalData = GlobalLock(hGlobal);
  else MessageBox(hAppWnd, "Could not lock global memory for clipboard
transfer",
                           "XWinClip", MB_OK);
  result = !(pszGlobalData == NULL);

  if (result)
  {
    // Copy the returned string into the global memory
    strcpy(pszGlobalData, pszReturnData);
    // Release the pointer to the global memory
    GlobalUnlock(hGlobal);
    pszGlobalData = NULL;
    // Push the selection data to the Windows clipboard
    SetClipboardData(CF_TEXT, hGlobal);
    // NOTE: Do not try to free pszGlobalData, it is owned by
    // Windows after the call to SetClipboardData ().
  }
  // Release the clipboard
  if (!CloseClipboard ())
        printf ("CloseClipboard () failed\n");
  return(result);
}

//---------------------------------------------------------
//---------------------------------------------------------
void CopyFromX11(char * DisplayName)
{
 Display *pDisplay;
 Window iMyWindow;
 unsigned char	*pszReturnData = NULL;

  pDisplay = XOpenDisplay(DisplayName);
  if (pDisplay == NULL)
  {
     MessageBox(hAppWnd, "Could not open display", "XWinClip", MB_OK);
     return;
  }

  // Create a messaging window
  iMyWindow = XCreateSimpleWindow (pDisplay,
				 RootWindow (pDisplay, 0),
				 1, 1,
				 500, 500,
				 0,
				 BlackPixel (pDisplay, 0),
				 BlackPixel (pDisplay, 0));

  XFlush (pDisplay);
  if (iMyWindow == 0)
  {
    MessageBox(hAppWnd, "Could not create a X11 window", "XWinClip", MB_OK);
  }
  else
  {
    XSelectInput (pDisplay, iMyWindow, ExposureMask);
    if (DoCopyFromX11(pDisplay, iMyWindow, &pszReturnData) )
    {
      // Convert the X clipboard string to DOS format
      UNIXtoDOS(&pszReturnData, strlen(pszReturnData));
      DoPasteToWindows(pszReturnData);
      // Free the data returned from XGetWindowProperty
      XFree(pszReturnData);
      pszReturnData = NULL;
    }
    XDestroyWindow (pDisplay, iMyWindow);
  }
  // Close the connection to X11
  XCloseDisplay(pDisplay);
}


//--------------------------------------------------------------------------
----
//--------------------------------------------------------------------------
----
char * GetDisplayMachine(int DisplayNum)
{
 static char buf[250];
 Display *pDisplay;
 Window   iWindow;
 Window  root_return, parent_return;
 Window  *children_return;
 int     nchildren_return;
 XTextProperty ClientMachine;
 int           iReturn;

    sprintf(buf, ":%d.0", DisplayNum);
    pDisplay = XOpenDisplay(buf);
    if (pDisplay == NULL)
    {
     strncat(buf, " can't open display", sizeof(buf) -1 - 4);
     return(buf);
    }
    iWindow = XDefaultRootWindow(pDisplay);
    if ( (iWindow == BadWindow) || (iWindow == None) )
    {
     strncpy(buf, "Could not get Root Window", sizeof(buf) -1);
     return(buf);
    }
    buf[0] = '\0';
    XQueryTree(pDisplay, iWindow, &root_return, &parent_return,
&children_return, &nchildren_return);
    if (nchildren_return > 0)
    {
      iWindow = children_return[0];
      XFree(children_return);
    }
    else
    {
      return(buf);
    }
    iReturn = XGetWMClientMachine(pDisplay, iWindow, &ClientMachine);
    if (iReturn == 0)
    {
     //strncpy(buf, "Could not get WMClientMachine", sizeof(buf) -1);
     return(buf);
    }
    strncpy(buf, ClientMachine.value, sizeof(buf) -1);
    XFree(ClientMachine.value);
    XCloseDisplay(pDisplay);
    buf[255] = '\0';
    return(buf);
}

//--------------------------------------------------------------------------
----
void CopyFromWindows(char * DisplayName)
{
 Display *pDisplay;
 Window   iWindow;
 Window   iMyWindow;
 XSelectionEvent   eventSelection;
 int      iReturn;
 char    *pszGlobalData;
 HGLOBAL  hGlobal;
 Atom     TargetsAtom;
 //Atom     atomClipboard;
 Atom	  atomUTF8String;
 BOOL     XLoopDone = FALSE;

 XTextProperty ClientMachine;
 int i;
 char * tmpstr;
 BOOL IsSelectionRequest = FALSE;

    pDisplay = XOpenDisplay(DisplayName);
    if (pDisplay == NULL)
    {
     MessageBox(hAppWnd, "Could not open display", "XWinClip", MB_OK);
     return;
    }

    // Create a messaging window
    iMyWindow = XCreateSimpleWindow (pDisplay,
				 RootWindow (pDisplay, 0),
				 1, 1,
				 500, 500,
				 0,
				 BlackPixel (pDisplay, 0),
				 BlackPixel (pDisplay, 0));

    if (iMyWindow == 0)
    {
      MessageBox(hAppWnd, "Could not create a X11 window", "XWinClip",
MB_OK);
    }
    XSelectInput (pDisplay, iMyWindow, StructureNotifyMask+ExposureMask);
    XFlush (pDisplay);

    atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
    if (atomUTF8String == None)
    {
      printf ("Could not create UTF8_STRING atom\n");
    }

    TargetsAtom = XInternAtom(pDisplay, "TARGETS", False);
    if (TargetsAtom == None)
    {
         printf ("Could not create TARGETS atom\n");
         // return;
    }

    iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
				  iMyWindow, CurrentTime);
    if (iReturn == BadAtom || iReturn == BadWindow)
    {
      printf ("Could not set XA_PRIMARY owner to Our window\n");
    }

    while (!XLoopDone /*|| IsSelectionRequest*/ )
    {
     XEvent xevent;
     XSelectionEvent	eventSelection;
      // Block until the next X event
      XNextEvent(pDisplay, &xevent);
      printf("\nXLoop new event\n");

      // Branch on the event type
      switch (xevent.type)
      {
        case SelectionRequest:
          IsSelectionRequest = TRUE;
          tmpstr = XGetAtomName(pDisplay,
xevent.xselectionrequest.property);
          printf("xevent.xselectionrequest.property %s\n", tmpstr);
          XFree(tmpstr);
          tmpstr = NULL;

	  if (xevent.xselectionrequest.target == TargetsAtom)
	  {
              Atom atTargetArr[2] = {atomUTF8String, XA_STRING};
              XLoopDone = FALSE;
              printf("target type TARGETS %d\n",
xevent.xselectionrequest.target);

 	      iReturn = XChangeProperty (pDisplay,
	      			     xevent.xselectionrequest.requestor,
	      			     xevent.xselectionrequest.property,
	      			     xevent.xselectionrequest.target,
	      			     8,
	      			     PropModeReplace,
	      			     (char *)(atTargetArr),
	      			     sizeof(atTargetArr));
	      if (iReturn == BadAlloc || iReturn == BadAtom
	          || iReturn == BadMatch || iReturn == BadValue
	          || iReturn == BadWindow)
	        {
	          printf ("SelectionRequest - XChangeProperty failed: %d\n",
	      	      iReturn);
	        }

	      // Setup selection notify xevent
	      eventSelection.type = SelectionNotify;
	      eventSelection.send_event = True;
	      eventSelection.display   = pDisplay;
	      eventSelection.requestor = xevent.xselectionrequest.requestor;
	      eventSelection.selection = xevent.xselectionrequest.selection;
	      eventSelection.target    = xevent.xselectionrequest.target;
	      eventSelection.property  = xevent.xselectionrequest.property;
	      eventSelection.time      = xevent.xselectionrequest.time;

	      // Notify the requesting window that the operation has completed
	      iReturn = XSendEvent (pDisplay,
	      			eventSelection.requestor,
	      			False,
	      			0L,
	      			(XEvent *) &eventSelection);
	      if (iReturn == BadValue || iReturn == BadWindow)
              {
	  	      printf ("XSendEvent () failed\n");
	      }
              XFlush(pDisplay);
          }
          else if (xevent.xselectionrequest.target == XA_STRING)
          {
              printf("target type XA_STRING %d\n",
xevent.xselectionrequest.target);
              XLoopDone = TRUE;
              // Access the clipboard
              if (!OpenClipboard (hAppWnd))
              {
                  printf ("OpenClipboard () failed\n");
                  return;
              }
              // Get a pointer to the clipboard text
              hGlobal = GetClipboardData (CF_TEXT);
              if (!hGlobal)
                {
                  printf ("GetClipboardData () failed\n");
                  return;
                }
              pszGlobalData = (char *) GlobalLock (hGlobal);

              // Convert DOS string to UNIX string */
              DOStoUNIX(pszGlobalData, strlen(pszGlobalData));

	      iReturn = XChangeProperty (pDisplay,
	      			     xevent.xselectionrequest.requestor,
	      			     xevent.xselectionrequest.property,
	      			     xevent.xselectionrequest.target,
	      			     8,
	      			     PropModeReplace,
	      			     pszGlobalData,
	      			     strlen(pszGlobalData) );
	      if (iReturn == BadAlloc || iReturn == BadAtom
	          || iReturn == BadMatch || iReturn == BadValue
	          || iReturn == BadWindow)
	        {
	          printf ("SelectionRequest - XChangeProperty failed: %d\n",
	      	      iReturn);
	        }
              // Release the clipboard data
              GlobalUnlock(hGlobal);
              pszGlobalData = NULL;
              CloseClipboard();

	      // Setup selection notify xevent
	      eventSelection.type = SelectionNotify;
	      eventSelection.send_event = True;
	      eventSelection.display   = pDisplay;
	      eventSelection.requestor = xevent.xselectionrequest.requestor;
	      eventSelection.selection = xevent.xselectionrequest.selection;
	      eventSelection.target    = xevent.xselectionrequest.target;
	      eventSelection.property  = xevent.xselectionrequest.property;
	      eventSelection.time      = xevent.xselectionrequest.time;

	      // Notify the requesting window that the operation has completed
	      iReturn = XSendEvent (pDisplay,
	      			eventSelection.requestor,
	      			False,
	      			0L,
	      			(XEvent *) &eventSelection);
	      if (iReturn == BadValue || iReturn == BadWindow)
              {
	  	      printf ("XSendEvent () failed\n");
	  	      //return;
	      }
              XFlush(pDisplay);
          }
          else
          {
              // Abort if invalid target type
              XLoopDone = TRUE;
              printf("invalid target type %d\n",
xevent.xselectionrequest.target);
	      // Setup selection notify xevent
	      eventSelection.type       = SelectionNotify;
	      eventSelection.send_event = True;
	      eventSelection.display    = pDisplay;
	      eventSelection.requestor  = xevent.xselectionrequest.requestor;
	      eventSelection.selection  = xevent.xselectionrequest.selection;
	      eventSelection.target     = xevent.xselectionrequest.target;
	      eventSelection.property   = None;
	      eventSelection.time       = xevent.xselectionrequest.time;

	      // Notify the requesting window that the operation is complete
	      iReturn = XSendEvent (pDisplay,
				    eventSelection.requestor,
				    False,
				    0L,
				    (XEvent *) &eventSelection);
	      if (iReturn == BadValue || iReturn == BadWindow)
              {
		  printf ("XSendEvent () failed\n");
		  //return;
	      }
              XFlush(pDisplay);
             /******************
             iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
				eventSelection.requestor, CurrentTime);
             if (iReturn == BadAtom || iReturn == BadWindow)
             {
               printf ("Could not set XA_PRIMARY owner back to last
window\n");
             }
              XFlush(pDisplay);
             **********/
          }
          break;

        case SelectionClear:
          IsSelectionRequest = FALSE;
          printf("SelectionClear message handler\n");
          break;
        default:
          IsSelectionRequest = FALSE;
          printf("default message handler\n");
          break;
      } // case
   }  // while

   XDestroyWindow(pDisplay, iMyWindow);
   XCloseDisplay(pDisplay);
}

//---------------------------------------------------------

//---------------------------------------------
// * Change \n to \r\n.  Reallocate string if necessary.
// ---------------------------------------------
void UNIXtoDOS (unsigned char **ppszData, int iLength)
{
  int			iNewlineCount = 0;
  unsigned char		*pszSrc = *ppszData;
  unsigned char		*pszEnd = pszSrc + iLength;
  unsigned char		*pszDest = NULL, *pszDestBegin = NULL;

#if 0
  printf ("UNIXtoDOS () - Original data:\n%s\n", *ppszData);
#endif

  // Count \n characters without leading \r */
  while (pszSrc < pszEnd)
    {
      // Skip ahead two character if found set of \r\n */
      if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n')
	{
	  pszSrc += 2;
	  continue;
	}

      // Increment the count if found naked \n */
      if (*pszSrc == '\n')
	{
	  iNewlineCount++;
	}

      pszSrc++;
    }

  // Return if no naked \n's */
  if (iNewlineCount == 0)
    return;

  // Allocate a new string */
  pszDestBegin = pszDest = malloc (iLength + iNewlineCount + 1);

  // Set source pointer to beginning of data string */
  pszSrc = *ppszData;

  // Loop through all characters in source string */
  while (pszSrc < pszEnd)
    {
      // Copy line endings that are already valid */
      if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n')
	{
	  *pszDest = *pszSrc;
	  *(pszDest + 1) = *(pszSrc + 1);
	  pszDest += 2;
	  pszSrc += 2;
	  continue;
	}

      // Add \r to naked \n's */
      if (*pszSrc == '\n')
	{
	  *pszDest = '\r';
	  *(pszDest + 1) = *pszSrc;
	  pszDest += 2;
	  pszSrc += 1;
	  continue;
	}

      // Copy normal characters */
      *pszDest = *pszSrc;
      pszSrc++;
      pszDest++;
    }

  // Put terminating null at end of new string */
  *pszDest = '\0';

  // Swap string pointers */
  free (*ppszData);
  *ppszData = pszDestBegin;

#if 0
  printf ("UNIXtoDOS () - Final string:\n%s\n", pszDestBegin);
#endif
}


//--------------------------------------------------------------------------
--
//  This was heavily inspired by, if not down right stolen from, Cygwin's
//  winsup/cygwin/fhandler.cc/fhandler_base::read ()
//--------------------------------------------------------------------------
--
void DOStoUNIX (char *pszSrc, int iLength)
{
  char			*pszDest = pszSrc;
  char			*pszEnd = pszSrc + iLength;

  // Loop until the last character */
  while (pszSrc < pszEnd)
    {
      // Copy the current source character to current destination character
*/
      *pszDest = *pszSrc;

      // Advance to the next source character */
      pszSrc++;

      // Don't advance the destination character if we need to drop an \r */
      if (*pszDest != '\r' || *pszSrc != '\n')
	pszDest++;
    }

  // Move the terminating null */
  *pszDest = '\0';
}



// -------------------------------------------------------------------------
-----------------
int main (int argc, char *argv[])
{
  HWND			hWnd;
  MSG			msg;

  ghInstance = GetModuleHandle (NULL);
  ghResInst  = LoadLibraryEx(/*C:\\cygwinDEV\\xwinclip\\*/"XWinclip.DLL",
NULL, LOAD_LIBRARY_AS_DATAFILE);
  printf("ghResInst = %d\n", ghResInst);

  // Create Windows messaging window
  hWnd = CreateMessagingWindow();

  // Loop for Windows events
  // Acquire and dispatch messages until a WM_QUIT message is received.
  while (GetMessage(&msg, NULL, 0, 0))
  {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
  }

  ////printf("Exiting xwinclip\n");
  CreateTrayIcon(hWnd, NIM_DELETE, 0, NULL, NULL);
  FreeLibrary(ghResInst);
  UnregisterClass(WINDOW_CLASS, ghInstance);

  return 0;
}


//--------------------------------------------------------------------------
----
// supported only local Displays from 0 to 9
//--------------------------------------------------------------------------
----
int SelectDir(const struct dirent * current)
{
         //(strlen(current->d_name) <= 2) &&
 return (
         (current->d_name[0] == 'X') &&
         (current->d_name[1] >= '0') &&
         (current->d_name[1] <= '9') &&
         (current->d_name[2] == '\0')
        );
}


//--------------------------------------------------------------------------
----
// to find displays
//---     /tpm/.X11-unix/X0  .. X4 .. Xn
//--------------------------------------------------------------------------
----
void RebuildTrayMenus(void)
{
 char buf[260];
 struct dirent **namelist;
 int i, n;

  for (i = 0; i < ARRAYSIZE(DisplayIds); i++)
  {
    if (DisplayIds[i])
    {
      DeleteMenu(hmToWin, 0, MF_BYPOSITION);
      DeleteMenu(hmToX11, 0, MF_BYPOSITION);
    }
  }

  i = scandir("/tmp/.X11-unix/", &namelist, SelectDir, alphasort);
  if (i < 0)
        printf("error scandir\n");
  else
  {
    bzero( (void *)DisplayIds, sizeof(DisplayIds));
    while (i--)
    {
      int n = namelist[i]->d_name[1] - '0';
      DisplayIds[n] = TRUE;
      /////////printf("%s\n", namelist[i]->d_name);
      free(namelist[i]);
    }
    free(namelist);
  }

  for (i = 0; i < ARRAYSIZE(DisplayIds); i++)
  {
    if (DisplayIds[i])
    {
      char * MachineName = GetDisplayMachine(i);
      sprintf(buf, "From %d (%s)", i, MachineName);
      AppendMenu(hmToWin, MF_ENABLED | MF_STRING, IDM_FROM + i, buf);
      sprintf(buf, "To %d (%s)", i, MachineName);
      AppendMenu(hmToX11, MF_ENABLED | MF_STRING, IDM_TO + i, buf);
    }
  }
}



//--------------------------------------------------------------------------
----
//--------------------------------------------------------------------------
----
LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM
lParam)
{
 static BOOL bShowing = TRUE;
 POINT Point;
 int CommandId;
    // cases for application messages
    switch (uMessage)
    {
        // command from application menu
        case WM_COMMAND:
            //use the GET_WM_COMMAND macro to unpack the commnad
            CommandId = GET_WM_COMMAND_ID(wParam, lParam);
            if ( (CommandId >= IDM_FROM) && (CommandId < IDM_FROM +
MAX_DISPLAYS) )
            {
                 // Copy From X11
                 char dispName[8];
                 sprintf(dispName, ":%d.0", CommandId - IDM_FROM);
                 CopyFromX11(dispName);
                 //printf("Done Copy From X11 %d\n", CommandId);
            }
            else if ( (CommandId >= IDM_TO) && (CommandId < IDM_TO +
MAX_DISPLAYS) )
            {
                // Copy To X11
                char dispName[8];
                sprintf(dispName, ":%d.0", CommandId - IDM_TO);
                CopyFromWindows(dispName);
                //printf("Done Copy To X11 %d\n", CommandId);
            }
            else if (CommandId == IDM_EXIT)
            {
               DestroyWindow(hWnd);
            }
            else
            {
               return DefWindowProc(hWnd, uMessage, wParam, lParam);
            }
            break;

	case MYWM_NOTIFYICON:
		switch (lParam)
		{
		case WM_LBUTTONDBLCLK:
                        if (bShowing)
                        {
			        ShowWindow(hWnd, SW_HIDE);
                        }
                        else
                        {
			        ShowWindow(hWnd, SW_SHOW);
			        SetForegroundWindow(hWnd);	// make us come to the front
                        }
                        bShowing = !bShowing;
			break;

		/*case WM_LBUTTONDOWN:
			switch (wParam)
			{
			}
			break; */

                case WM_RBUTTONDOWN:
                        RebuildTrayMenus();
                        DrawMenuBar(hWnd);
			break;

		case WM_RBUTTONUP:
                        GetCursorPos(&Point);
                        if ( !TrackPopupMenuEx(hPopupMnu,
                            /*TPM_RIGHTBUTTON |*/ TPM_RIGHTALIGN,	//
screen-position and mouse-button flags
                            Point.x, Point.y, hWnd, NULL)	// points to RECT
that specifies no-dismissal area
                         ) printf("popup menu failed at X:%d, Y:%d\n",
Point.x, Point.y);
		        break;

		default:
			break;
		}
		break;

        case WM_DESTROY:  // message: window being destroyed
            PostQuitMessage(0);
            break;

        default:          // Passes it on if unproccessed
            return DefWindowProc(hWnd, uMessage, wParam, lParam);
    }
    return 0;
}

//--------------------------------------------------------------------------
----------------
//--------------------------------------------------------------------------
-
BOOL CreateTrayIcon(HWND hWnd, DWORD dwMessage, UINT uID, HICON hIcon, PSTR
pszTip)
{
 BOOL res;
 NOTIFYICONDATA tnd;

	tnd.cbSize		= sizeof(NOTIFYICONDATA);
	tnd.hWnd		= hWnd;
	tnd.uID			= uID;

	tnd.uFlags		= NIF_MESSAGE|NIF_ICON|NIF_TIP;
	tnd.uCallbackMessage	= MYWM_NOTIFYICON;
	tnd.hIcon		= hIcon;
	if (pszTip)
	{
		lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));
	}
	else
	{
		tnd.szTip[0] = '\0';
	}
	res = Shell_NotifyIcon(dwMessage, &tnd);

	return res;
}


//--------------------------------------------------------------------------
---
void CreateTrayMenu(void)
{
  hPopupMnu = CreatePopupMenu();
  hmToWin = CreatePopupMenu();
  hmToX11 = CreatePopupMenu();
  AppendMenu(hPopupMnu, MF_ENABLED | MF_POPUP | MF_STRING, (UINT)hmToWin,
"Copy TO Windows");
  AppendMenu(hPopupMnu, MF_ENABLED | MF_POPUP | MF_STRING, (UINT)hmToX11,
"Copy TO X11");
  AppendMenu(hPopupMnu, MF_SEPARATOR, 0, NULL);
  AppendMenu(hPopupMnu, MF_ENABLED | MF_STRING, IDM_EXIT, "Exit (Alt+F4)");
}

//--------------------------------------------------------------------------
---
HWND CreateMessagingWindow(void)
{
 WNDCLASS  wc;
 HICON hIconApp;
 HICON hIconTray;

  hIconApp  = (HICON)LoadImage(ghResInst, MAKEINTRESOURCE(ID_ICON_APP),
IMAGE_ICON, 16, 16, 0);
  hIconTray = (HICON)LoadImage(ghResInst, MAKEINTRESOURCE(ID_ICON_TRAY),
IMAGE_ICON, 16, 16, 0);
  //printf("hIconApp = %d\n", hIconApp);
  //printf("hIconTray = %d\n", hIconTray);

  CreateTrayMenu();
  //printf("hPopupMnu %d\n", hPopupMnu);

  // Setup our window class */
  wc.style = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = WindowProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = ghInstance;
  wc.hIcon = hIconApp;
  wc.hCursor = 0;
  wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = WINDOW_CLASS;
  RegisterClass (&wc);

  // Create the window
  hAppWnd = CreateWindowExA (0,	// Extended styles
			  WINDOW_CLASS,		// Class name
			  WINDOW_TITLE,		// Window name
			  WS_OVERLAPPED,	// Not visible anyway
			  CW_USEDEFAULT,	// Horizontal position
			  CW_USEDEFAULT,	// Vertical position
			  50,	// Right edge   CW_USEDEFAULT
			  50,	// Bottom edge CW_USEDEFAULT
			  (HWND) NULL,		// No parent or owner window
			  (HMENU) NULL,		// No menu
			  ghInstance,// Instance handle
			  NULL);		// ScreenPrivates
  assert (hAppWnd != NULL);

  CreateTrayIcon(hAppWnd, NIM_ADD, 0, hIconTray, "XClipboard 2 Win");

  return(hAppWnd);
}

Any advice ?
			Thanks.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]