Esempio n. 1
1
bool saveHBitmapIntoClipboard(HBITMAP   sourceBitmap,
                              const int width,
                              const int height)
{
    // see ui/base/clipboard/clipboard_win.cc for details
    HDC dc = ::GetDC(NULL);
    HDC compatible_dc = ::CreateCompatibleDC(NULL);
    HDC source_dc = ::CreateCompatibleDC(NULL);

    // This is the HBITMAP we will eventually write to the clipboard
    HBITMAP hbitmap = ::CreateCompatibleBitmap(dc, width, height);
    if (!hbitmap) {
        // Failed to create the bitmap
        ::DeleteDC(compatible_dc);
        ::DeleteDC(source_dc);
        ::ReleaseDC(NULL, dc);
        return false;
    }

    HBITMAP old_hbitmap = (HBITMAP)SelectObject(compatible_dc, hbitmap);
    HBITMAP old_source = (HBITMAP)SelectObject(source_dc, sourceBitmap);

    // Now we need to blend it into an HBITMAP we can place on the clipboard
    BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
    ::GdiAlphaBlend(compatible_dc, 0, 0, width, height,
                    source_dc, 0, 0, width, height, bf);

    // Clean up all the handles we just opened
    ::SelectObject(compatible_dc, old_hbitmap);
    ::SelectObject(source_dc, old_source);
    ::DeleteDC(compatible_dc);
    ::DeleteDC(source_dc);
    ::ReleaseDC(NULL, dc);

    ClipboardGuard clipboardGuard(GetClipboardOwner());
    EmptyClipboard();
    HANDLE ret = SetClipboardData(CF_BITMAP, hbitmap);
    if (!ret) {
        ::DeleteObject(hbitmap);
    }
    return ret != 0;
}
Esempio n. 2
0
GdkWindow *gdk_selection_owner_get(GdkAtom selection)
{
   GdkWindow *window;
   gchar *sel_name;

#if 0
   /* XXX Hmm, gtk selections seem to work best with this. This causes
    * gtk to always get the clipboard contents from Windows, and not
    * from the editable's own stashed-away copy.
    */
   return NULL;
#else
   if (selection != gdk_clipboard_atom)
      window = NULL;
   else {
      window = gdk_window_lookup(GetClipboardOwner());
      if (window == NULL)
         window = (GdkWindow *)GetClipboardOwner();
   }

#endif

   GDK_NOTE(DND,
            (sel_name = gdk_atom_name(selection),
             g_print("gdk_selection_owner_get: %#x (%s) = %#x\n",
                     selection, sel_name,
                     (window ? GDK_DRAWABLE_XID(window) : 0)),
             g_free(sel_name)));

   return window;
}
Esempio n. 3
0
File: noise.c Progetto: rdebath/sgt
/*
 * This function is called on a timer, and it will monitor
 * frequently changing quantities such as the state of physical and
 * virtual memory, the state of the process's message queue, which
 * window is in the foreground, which owns the clipboard, etc.
 */
void noise_regular(void)
{
    HWND w;
    DWORD z;
    POINT pt;
    MEMORYSTATUS memstat;
    FILETIME times[4];

    w = GetForegroundWindow();
    random_add_noise(&w, sizeof(w));
    w = GetCapture();
    random_add_noise(&w, sizeof(w));
    w = GetClipboardOwner();
    random_add_noise(&w, sizeof(w));
    z = GetQueueStatus(QS_ALLEVENTS);
    random_add_noise(&z, sizeof(z));

    GetCursorPos(&pt);
    random_add_noise(&pt, sizeof(pt));

    GlobalMemoryStatus(&memstat);
    random_add_noise(&memstat, sizeof(memstat));

    GetThreadTimes(GetCurrentThread(), times, times + 1, times + 2,
		   times + 3);
    random_add_noise(&times, sizeof(times));
    GetProcessTimes(GetCurrentProcess(), times, times + 1, times + 2,
		    times + 3);
    random_add_noise(&times, sizeof(times));
}
Esempio n. 4
0
int
XSetSelectionOwner(
    Display *display,
    Atom selection,
    Window owner,
    Time time)
{
    HWND hwnd = owner ? TkWinGetHWND(owner) : NULL;
    Tk_Window tkwin;

    /*
     * This is a gross hack because the Tk_InternAtom interface is broken. It
     * expects a Tk_Window, even though it only needs a Tk_Display.
     */

    tkwin = (Tk_Window) TkGetMainInfoList()->winPtr;

    if (selection == Tk_InternAtom(tkwin, "CLIPBOARD")) {
	/*
	 * Only claim and empty the clipboard if we aren't already the owner
	 * of the clipboard.
	 */

	if (GetClipboardOwner() != hwnd) {
	    UpdateClipboard(hwnd);
	}
    }
    return Success;
}
Esempio n. 5
0
static DWORD WINAPI set_clipboard_data_thread(LPVOID arg)
{
    HWND hwnd = arg;
    HANDLE ret;

    SetLastError( 0xdeadbeef );
    if (GetClipboardOwner() == hwnd)
    {
        SetClipboardData( CF_WAVE, 0 );
        todo_wine ok( IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData failed\n", thread_from_line );
        ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
        ok( ret != 0, "%u: SetClipboardData failed err %u\n", thread_from_line, GetLastError() );
    }
    else
    {
        SetClipboardData( CF_WAVE, 0 );
        todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
                      thread_from_line, GetLastError());
        ok( !IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData succeeded\n", thread_from_line );
        ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
        todo_wine ok( !ret, "%u: SetClipboardData succeeded\n", thread_from_line );
        todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
                      thread_from_line, GetLastError());
    }
    return 0;
}
Esempio n. 6
0
/*
 * This function is called on a timer, and it will monitor
 * frequently changing quantities such as the state of physical and
 * virtual memory, the state of the process's message queue, which
 * window is in the foreground, which owns the clipboard, etc.
 */
void noise_regular(void)
{
    HWND w;
    DWORD z;
    POINT pt;
    MEMORYSTATUS memstat;
    FILETIME times[4];

    w = GetForegroundWindow();
    random_add_noise(NOISE_SOURCE_FGWINDOW, &w, sizeof(w));
    w = GetCapture();
    random_add_noise(NOISE_SOURCE_CAPTURE, &w, sizeof(w));
    w = GetClipboardOwner();
    random_add_noise(NOISE_SOURCE_CLIPBOARD, &w, sizeof(w));
    z = GetQueueStatus(QS_ALLEVENTS);
    random_add_noise(NOISE_SOURCE_QUEUE, &z, sizeof(z));

    GetCursorPos(&pt);
    random_add_noise(NOISE_SOURCE_CURSORPOS, &pt, sizeof(pt));

    GlobalMemoryStatus(&memstat);
    random_add_noise(NOISE_SOURCE_MEMINFO, &memstat, sizeof(memstat));

    GetThreadTimes(GetCurrentThread(), times, times + 1, times + 2,
		   times + 3);
    random_add_noise(NOISE_SOURCE_THREADTIME, &times, sizeof(times));
    GetProcessTimes(GetCurrentProcess(), times, times + 1, times + 2,
		    times + 3);
    random_add_noise(NOISE_SOURCE_PROCTIME, &times, sizeof(times));
}
Esempio n. 7
0
static PyObject *
py_get_clipboard_owner(PyObject* self, PyObject* args)
{

  CHECK_NO_ARGS2(args, "GetClipboardOwner");

  HWND rc;
  Py_BEGIN_ALLOW_THREADS;
  rc = GetClipboardOwner();
  Py_END_ALLOW_THREADS;

  if (!rc)
    return ReturnAPIError("GetClipboardOwner");
  return PyWinLong_FromHANDLE(rc);

  // @comm The clipboard can still contain data even if the clipboard is not
  // currently owned.<nl>
  // In general, the clipboard owner is the window that last placed data in
  // clipboard. The EmptyClipboard function assigns clipboard ownership. 

  // @pyseeapi GetClipboardOwner

  // @rdesc If the function succeeds, the return value is the handle of the
  // window that owns the clipboard. 
  // If the function fails, win32api.error is raised with the GetLastError
  // info.

}
Esempio n. 8
0
bool ClipboardUtil::getTextFromClipboard(std::string *result, unsigned format)
{
    //KITDIAG_ASSERT(result);

    if (!hasUnsignedFormat(format)) {
        return false;
    }

    ClipboardGuard clipboardGuard(GetClipboardOwner());
    if (!clipboardGuard.isOpen()) {
        return false;
    }

    bool foundIt = false;
    HANDLE hData = GetClipboardData(format);
    LPVOID pData = GlobalLock(hData);
    if (pData) {
        if (format == CF_TEXT) {
            *result = (char*)pData;
            foundIt = true;
        }
        else if (format == CF_UNICODETEXT) {
            std::wstring wideStr = (wchar_t*)pData;
            UtfUtil::utf16ToUtf8(wideStr, result);
            foundIt = true;
        }
    }
    GlobalUnlock(hData);
    return foundIt;
}
Esempio n. 9
0
static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    static UINT wm_drawclipboard;
    static UINT wm_clipboardupdate;
    static UINT wm_destroyclipboard;
    LRESULT ret;

    switch(msg) {
    case WM_DRAWCLIPBOARD:
        EnterCriticalSection(&clipboard_cs);
        wm_drawclipboard++;
        LeaveCriticalSection(&clipboard_cs);
        break;
    case WM_CHANGECBCHAIN:
        if (next_wnd == (HWND)wp)
            next_wnd = (HWND)lp;
        else if (next_wnd)
            SendMessageA(next_wnd, msg, wp, lp);
        break;
    case WM_DESTROYCLIPBOARD:
        wm_destroyclipboard++;
        ok( GetClipboardOwner() == hwnd, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
        break;
    case WM_CLIPBOARDUPDATE:
        wm_clipboardupdate++;
        break;
    case WM_USER:
        ChangeClipboardChain(hwnd, next_wnd);
        PostQuitMessage(0);
        break;
    case WM_USER+1:
        ret = wm_drawclipboard;
        wm_drawclipboard = 0;
        return ret;
    case WM_USER+2:
        ret = wm_clipboardupdate;
        wm_clipboardupdate = 0;
        return ret;
    case WM_USER+3:
        ret = wm_destroyclipboard;
        wm_destroyclipboard = 0;
        return ret;
    }

    return DefWindowProcA(hwnd, msg, wp, lp);
}
Esempio n. 10
0
PUBLIC boolean_t
we_lost_clipboard (void)
{
  boolean_t retval;

  retval = GetClipboardOwner () != cygwin_sdlwindow ();
  return retval;
}
Esempio n. 11
0
int
pygame_scrap_lost (void)
{
    if (!pygame_scrap_initialized ())
    {
        PyErr_SetString (PyExc_SDLError, "scrap system not initialized.");
        return 0;
    }
    return (GetClipboardOwner () != SDL_Window);
}
Esempio n. 12
0
bool ClipboardUtil::emptyClipboard()
{
    ClipboardGuard clipboardGuard(GetClipboardOwner());
    if (!clipboardGuard.isOpen()) {
        return false;
    }
    BOOL ret = EmptyClipboard();
    //KITDIAG_ASSERT(ret != 0);
    return ret != 0;
}
LRESULT CALLBACK VDAgent::wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    VDAgent* a = _singleton;

    switch (message) {
    case WM_DISPLAYCHANGE:
        vd_printf("Display change");
        // the desktop layout needs to be updated for the mouse
        // position to be scaled correctly
        if (!a->_updating_display_config)
            a->_desktop_layout->get_displays();
        break;
    case WM_TIMER:
        a->send_input();
        break;
    case WM_CHANGECBCHAIN:
        if (a->_hwnd_next_viewer == (HWND)wparam) {
            a->_hwnd_next_viewer = (HWND)lparam;
        } else if (a->_hwnd_next_viewer) {
            SendMessage(a->_hwnd_next_viewer, message, wparam, lparam);
        }
        break;
    case WM_CLIPBOARDUPDATE:
    case WM_DRAWCLIPBOARD:
        if (a->_hwnd != GetClipboardOwner()) {
            a->set_clipboard_owner(a->owner_none);
            a->on_clipboard_grab();
        }
        if (a->_hwnd_next_viewer) {
            SendMessage(a->_hwnd_next_viewer, message, wparam, lparam);
        }
        break;
    case WM_RENDERFORMAT:
        a->on_clipboard_request((UINT)wparam);
        break;
    case WM_ENDSESSION:
        if (wparam) {
            vd_printf("Session ended");
            if (a->_clipboard_owner == owner_guest) {
                a->set_clipboard_owner(owner_none);
            }
            a->set_control_event(CONTROL_STOP);
        }
        break;
    case WM_WTSSESSION_CHANGE:
        if (wparam == WTS_SESSION_LOGON) {
            a->set_control_event(CONTROL_LOGON);
        }
        break;
    default:
        return DefWindowProc(hwnd, message, wparam, lparam);
    }
    return 0;
}
Esempio n. 14
0
PUBLIC boolean_t
we_lost_clipboard(void)
{
#if defined(X11_SCRAP)
/* * */
	return ( XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window );

#elif defined(WIN_SCRAP)
/* * */
	return ( GetClipboardOwner() != SDL_Window );

#endif /* scrap type */
}
Esempio n. 15
0
static void test_ClipboardOwner(void)
{
    HWND hWnd1, hWnd2;
    BOOL ret;

    SetLastError(0xdeadbeef);
    ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef,
       "could not perform clipboard test: clipboard already owned\n");

    hWnd1 = CreateWindowExA(0, "static", NULL, WS_POPUP,
                                 0, 0, 10, 10, 0, 0, 0, NULL);
    ok(hWnd1 != 0, "CreateWindowExA error %d\n", GetLastError());
    trace("hWnd1 = %p\n", hWnd1);

    hWnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP,
                                 0, 0, 10, 10, 0, 0, 0, NULL);
    ok(hWnd2 != 0, "CreateWindowExA error %d\n", GetLastError());
    trace("hWnd2 = %p\n", hWnd2);

    SetLastError(0xdeadbeef);
    ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
    ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN || broken(GetLastError() == 0xdeadbeef), /* wow64 */
       "wrong error %u\n", GetLastError());

    ok(OpenClipboard(0), "OpenClipboard failed\n");
    ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
    ok(!OpenClipboard(hWnd1), "OpenClipboard should fail since clipboard already opened\n");
    ret = CloseClipboard();
    ok( ret, "CloseClipboard error %d\n", GetLastError());

    ok(OpenClipboard(hWnd1), "OpenClipboard failed\n");

    SetLastError(0xdeadbeef);
    ret = OpenClipboard(hWnd2);
    ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
       "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n");
    ret = EmptyClipboard();
    ok( ret, "EmptyClipboard error %d\n", GetLastError());
    ok(GetClipboardOwner() == hWnd1, "clipboard should be owned by %p, not by %p\n", hWnd1, GetClipboardOwner());

    SetLastError(0xdeadbeef);
    ret = OpenClipboard(hWnd2);
    ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
       "OpenClipboard should fail without setting last error valuei, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());

    ret = CloseClipboard();
    ok( ret, "CloseClipboard error %d\n", GetLastError());
    ok(GetClipboardOwner() == hWnd1, "clipboard should still be owned\n");

    ret = DestroyWindow(hWnd1);
    ok( ret, "DestroyWindow error %d\n", GetLastError());
    ret = DestroyWindow(hWnd2);
    ok( ret, "DestroyWindow error %d\n", GetLastError());
    SetLastError(0xdeadbeef);
    ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
}
Esempio n. 16
0
bool QClipboard::ownsMode(Mode mode) const
{
    if (mode == Clipboard) {
        QClipboardData *d = clipboardData();
#if !defined(Q_OS_WINCE)
        return d->iData && OleIsCurrentClipboard(d->iData) == S_OK;
#else
        return d->iData && GetClipboardOwner() == d->clipBoardViewer->internalWinId();
#endif
    } else {
        return false;
    }
}
void ClientConnection::ProcessLocalClipboardChange()
{
	vnclog.Print(2, _T("Clipboard changed\n"));
	
	HWND hOwner = GetClipboardOwner();
	if (hOwner == m_hwnd) {
		vnclog.Print(2, _T("We changed it - ignore!\n"));
	} else if (!m_initialClipboardSeen) {
		vnclog.Print(2, _T("Don't send initial clipboard!\n"));
		m_initialClipboardSeen = true;
	} else if (!m_opts.m_DisableClipboard) {
		
		// The clipboard should not be modified by more than one thread at once
		omni_mutex_lock l(m_clipMutex);
		
		if (OpenClipboard(m_hwnd)) { 
			HGLOBAL hglb = GetClipboardData(CF_TEXT); 
			if (hglb == NULL) {
				CloseClipboard();
			} else {
				LPSTR lpstr = (LPSTR) GlobalLock(hglb);  
				
				char *contents = new char[strlen(lpstr) + 1];
				char *unixcontents = new char[strlen(lpstr) + 1];
				strcpy(contents,lpstr);
				GlobalUnlock(hglb); 
				CloseClipboard();       		
				
				// Translate to Unix-format lines before sending
				int j = 0;
				for (int i = 0; contents[i] != '\0'; i++) {
					if (contents[i] != '\x0d') {
						unixcontents[j++] = contents[i];
					}
				}
				unixcontents[j] = '\0';
				try {
					SendClientCutText(unixcontents, strlen(unixcontents));
				} catch (WarningException &e) {
					vnclog.Print(0, _T("Exception while sending clipboard text : %s\n"), e.m_info);
					DestroyWindow(m_hwnd);
				}
				delete [] contents; 
				delete [] unixcontents;
			}
		}
	}
	// Pass the message to the next window in clipboard viewer chain
	::SendMessage(m_hwndNextViewer, WM_DRAWCLIPBOARD , 0,0); 
}
Esempio n. 18
0
std::unique_ptr<Clipboard> Clipboard::Capture() {
  auto clipboard = std::make_unique<Clipboard>(GetClipboardOwner());
  if (clipboard == nullptr)
    return nullptr;

  UINT format_id = 0;
  for (auto i = 0, l = CountClipboardFormats(); i < l; ++i) {
    format_id = EnumClipboardFormats(format_id);
    if (format_id == 0)  // error
      break;

    auto handle = GetClipboardData(format_id);
    if (handle == NULL)  // error
      continue;

    std::unique_ptr<Format> format;

    if (format_id == CF_BITMAP) {
      // ignore

    } else if (format_id == CF_ENHMETAFILE) {
      auto meta_file =
          CopyEnhMetaFile(reinterpret_cast<HENHMETAFILE>(handle), nullptr);
      if (meta_file == NULL)  // error
        continue;

      format = std::make_unique<MetaFileFormat>(meta_file);

    } else {
      auto size = GlobalSize(handle);
      auto memory = GlobalLock(handle);
      if (memory == nullptr)  // error
        continue;

      format = std::make_unique<Format>(format_id, size);
      memcpy(format->Get(), memory, size);

      GlobalUnlock(handle);
    }

    if (format != nullptr)
      clipboard->Add(std::move(format));
  }

  if (clipboard->IsEmpty())
    return nullptr;

  return clipboard;
}
Esempio n. 19
0
int lost_scrap(void)
{
    int retval = 0;

#if defined(WZ_WS_X11)
    Lock_Display();
    retval = ( XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window );
    Unlock_Display();
#elif defined(WZ_WS_WIN)
    retval = ( GetClipboardOwner() != SDL_Window );
#elif defined(WZ_WS_QNX)
    retval = ( PhInputGroup(NULL) != InputGroup );
#endif /* scrap type */
    return(retval);
}
Esempio n. 20
0
bool hasUnsignedFormat(unsigned format)
{
    ClipboardGuard clipboardGuard(GetClipboardOwner());
    if (!clipboardGuard.isOpen()) {
        return false;
    }

    bool didFind = false;
    UINT enumFormat = EnumClipboardFormats(0);
    while (enumFormat && !didFind) {
        if (enumFormat == format) {
            didFind = true;
        }
        enumFormat = EnumClipboardFormats(enumFormat);
    }

    return didFind;
}
Esempio n. 21
0
static HWND
GetCurrentHWND( void )
{
        const char* hwndstr;
        HWND whandle = NULL;

        #ifdef SDL_SUPPORT

        /*
         *      If SDL is supported we will try to get the HWND from SDL
         */
        SDL_SysWMinfo winfo;
        SDL_GetWMInfo( &winfo );
        whandle = winfo.window;

        if ( !whandle ) {

        #endif

        #pragma warning( disable: 4047 ) // 'HWND' differs in levels of indirection from 'Int32'

        /*
         *      Try to get the HWND from the process environment settings
         */
        hwndstr = GUCEFGetEnv( "HWND" );
        if ( hwndstr )
        {
                whandle = (HWND) Str_To_Int( hwndstr );
        }
        else
        {
                /*
                 *      If all previous attempts failed then try to use the previous
                 *      clipboard owner (if there is one).
                 */
                whandle = GetClipboardOwner();
        }

        #ifdef SDL_SUPPORT
        }
        #endif

        return whandle;
}
void ClientConnection::ProcessLocalClipboardChange()
{
	vnclog.Print(2, _T("Clipboard changed\n"));
	
	HWND hOwner = GetClipboardOwner();

	//adzm 2010-05-11 - Ignore clipboard while initializing (copying a password, for example, will end up sending a packet and causing a failure)
	if (!m_running)
	{
		vnclog.Print(2, _T("Ignore Clipboard while initializing!\n"));
		//m_initialClipboardSeen = true;
	}
	else if (m_settingClipboardViewer)
	{
		vnclog.Print(2, _T("Ignore Clipboard while setting viewer!\n"));
		//m_initialClipboardSeen = true;
	}
	else if (m_pFileTransfer->m_fFileTransferRunning ||m_pFileTransfer->m_fFileUploadRunning || m_pFileTransfer->m_fFileDownloadRunning)
	{
		vnclog.Print(2, _T("Ignore Clipboard while FT is buzy!\n"));
		//m_initialClipboardSeen = true;
	}
	else if (hOwner == m_hwndcn) {
		vnclog.Print(2, _T("We changed it - ignore!\n"));
	/*} else if (!m_initialClipboardSeen) {
		vnclog.Print(2, _T("Don't send initial clipboard!\n"));
		m_initialClipboardSeen = true;*/
	} else if (!m_opts.m_DisableClipboard && !m_opts.m_ViewOnly) {
		UpdateRemoteClipboard();
	}
	// Pass the message to the next window in clipboard viewer chain
	if (m_hwndNextViewer != NULL && m_hwndNextViewer != (HWND)INVALID_HANDLE_VALUE) {
		vnclog.Print(6, _T("Passing WM_DRAWCLIPBOARD to 0x%08x\n"), m_hwndNextViewer);
		// use SendNotifyMessage instead of SendMessage so misbehaving or hung applications
		// (like ourself before this) won't cause our thread to hang.
		::SendNotifyMessage(m_hwndNextViewer, WM_DRAWCLIPBOARD , 0,0); 
	} else {
		vnclog.Print(6, _T("No next window in chain; WM_DRAWCLIPBOARD will not be passed\n"), m_hwndNextViewer);
	}
}
Esempio n. 23
0
bool ClipboardUtil::getWStringData(std::wstring *result, const std::string& format)
{
    //KITDIAG_ASSERT(result);

    UINT clipFormat = getClipboardFormat(format.c_str());
    if (clipFormat == 0) {
        return false;
    }

    if (!hasUnsignedFormat(clipFormat)) {
        return false;
    }

    ClipboardGuard clipboardGuard(GetClipboardOwner());
    if (!clipboardGuard.isOpen()) {
        return false;
    }
    HANDLE hData = GetClipboardData(clipFormat);
    LPVOID pData = GlobalLock(hData);
    *result = (wchar_t *)pData;
    GlobalUnlock(hData);
    return true;
}
Esempio n. 24
0
bool ClipboardUtil::getAvailableClipboardFormats(std::vector<std::string> *formatsArray)
{
    //KITDIAG_ASSERT(formatsArray);
    ClipboardGuard clipboardGuard(GetClipboardOwner());
    if (!clipboardGuard.isOpen()) {
        return false;
    }

    formatsArray->clear();
    char formatName[100];
    std::string formatNameString;
    UINT uFormat = EnumClipboardFormats(0);
    while (uFormat) {
        if (getStandardClipboardFormatName(&formatNameString, uFormat)) {
            formatsArray->push_back(formatNameString);
        }
        else if (GetClipboardFormatNameA(uFormat, formatName, sizeof(formatName))) {
            formatNameString = formatName;
            formatsArray->push_back(formatNameString);
        }
        uFormat = EnumClipboardFormats(uFormat);
    }
    return true;
}
Esempio n. 25
0
/* This is the fastpoll function which gathers up info by calling various api's */
BOOL FastPoll (void)
{
	int nOriginalRandIndex = nRandIndex;
	static BOOL addedFixedItems = FALSE;
	FILETIME creationTime, exitTime, kernelTime, userTime;
	SIZE_T minimumWorkingSetSize, maximumWorkingSetSize;
	LARGE_INTEGER performanceCount;
	MEMORYSTATUS memoryStatus;
	HANDLE handle;
	POINT point;

	/* Get various basic pieces of system information */
	RandaddIntPtr (GetActiveWindow ());	/* Handle of active window */
	RandaddIntPtr (GetCapture ());	/* Handle of window with mouse
					   capture */
	RandaddIntPtr (GetClipboardOwner ());	/* Handle of clipboard owner */
	RandaddIntPtr (GetClipboardViewer ());	/* Handle of start of
						   clpbd.viewer list */
	RandaddIntPtr (GetCurrentProcess ());	/* Pseudohandle of current
						   process */
	RandaddInt32 (GetCurrentProcessId ());	/* Current process ID */
	RandaddIntPtr (GetCurrentThread ());	/* Pseudohandle of current
						   thread */
	RandaddInt32 (GetCurrentThreadId ());	/* Current thread ID */
	RandaddInt32 (GetCurrentTime ());	/* Milliseconds since Windows
						   started */
	RandaddIntPtr (GetDesktopWindow ());	/* Handle of desktop window */
	RandaddIntPtr (GetFocus ());	/* Handle of window with kb.focus */
	RandaddInt32 (GetInputState ());	/* Whether sys.queue has any events */
	RandaddInt32 (GetMessagePos ());	/* Cursor pos.for last message */
	RandaddInt32 (GetMessageTime ());	/* 1 ms time for last message */
	RandaddIntPtr (GetOpenClipboardWindow ());	/* Handle of window with
							   clpbd.open */
	RandaddIntPtr (GetProcessHeap ());	/* Handle of process heap */
	RandaddIntPtr (GetProcessWindowStation ());	/* Handle of procs
							   window station */
	RandaddInt32 (GetQueueStatus (QS_ALLEVENTS));	/* Types of events in
							   input queue */

	/* Get multiword system information */
	GetCaretPos (&point);	/* Current caret position */
	RandaddBuf ((unsigned char *) &point, sizeof (POINT));
	GetCursorPos (&point);	/* Current mouse cursor position */
	RandaddBuf ((unsigned char *) &point, sizeof (POINT));

	/* Get percent of memory in use, bytes of physical memory, bytes of
	   free physical memory, bytes in paging file, free bytes in paging
	   file, user bytes of address space, and free user bytes */
	memoryStatus.dwLength = sizeof (MEMORYSTATUS);
	GlobalMemoryStatus (&memoryStatus);
	RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS));

	/* Get thread and process creation time, exit time, time in kernel
	   mode, and time in user mode in 100ns intervals */
	handle = GetCurrentThread ();
	GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
	RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
	handle = GetCurrentProcess ();
	GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
	RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));

	/* Get the minimum and maximum working set size for the current
	   process */
	GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
				  &maximumWorkingSetSize);
	RandaddIntPtr (minimumWorkingSetSize);
	RandaddIntPtr (maximumWorkingSetSize);

	/* The following are fixed for the lifetime of the process so we only
	   add them once */
	if (addedFixedItems == 0)
	{
		STARTUPINFO startupInfo;

		/* Get name of desktop, console window title, new window
		   position and size, window flags, and handles for stdin,
		   stdout, and stderr */
		startupInfo.cb = sizeof (STARTUPINFO);
		GetStartupInfo (&startupInfo);
		RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO));
		addedFixedItems = TRUE;
	}
	/* The docs say QPC can fail if appropriate hardware is not
	   available. It works on 486 & Pentium boxes, but hasn't been tested
	   for 386 or RISC boxes */
	if (QueryPerformanceCounter (&performanceCount))
		RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER));
	else
	{
		/* Millisecond accuracy at best... */
		DWORD dwTicks = GetTickCount ();
		RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
	}

	// CryptoAPI: We always have a valid CryptoAPI context when we arrive here but
	//            we keep the check for clarity purpose
	if ( !CryptoAPIAvailable )
		return FALSE;
	if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer)) 
	{
		RandaddBuf (buffer, sizeof (buffer));
		burn (buffer, sizeof(buffer));
	}
	else
	{
		/* return error in case CryptGenRandom fails */
		CryptoAPILastError = GetLastError ();
		return FALSE;
	}

	/* Apply the pool mixing function */
	Randmix();

	/* Restore the original pool cursor position. If this wasn't done, mouse coordinates
	   could be written to a limited area of the pool, especially when moving the mouse
	   uninterruptedly. The severity of the problem would depend on the length of data
	   written by FastPoll (if it was equal to the size of the pool, mouse coordinates
	   would be written only to a particular 4-byte area, whenever moving the mouse
	   uninterruptedly). */
	nRandIndex = nOriginalRandIndex;

	return TRUE;
}
Esempio n. 26
0
static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	static cliprdrContext *cliprdr = NULL;

	switch (Msg)
	{
		case WM_CREATE:
			cliprdr = (cliprdrContext *)((CREATESTRUCT *)lParam)->lpCreateParams;
			cliprdr->hwndNextViewer = SetClipboardViewer(hWnd);

			if (cliprdr->hwndNextViewer == NULL && GetLastError() != 0)
			{
				DEBUG_CLIPRDR("error: SetClipboardViewer failed with 0x%0x.", GetLastError());
			}
			cliprdr->hwndClipboard = hWnd;
			break;

		case WM_CLOSE:
			ChangeClipboardChain(hWnd, cliprdr->hwndNextViewer);
			break;

		case WM_CHANGECBCHAIN:
			if (cliprdr->hwndNextViewer == (HWND)wParam)
			{
				cliprdr->hwndNextViewer = (HWND)lParam;
			}
			else if (cliprdr->hwndNextViewer != NULL)
			{
				SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam);
			}
			break;

		case WM_DRAWCLIPBOARD:
			if (cliprdr->channel_initialized)
			{
				if (GetClipboardOwner() != cliprdr->hwndClipboard)
				{
						if (!cliprdr->hmem)
						{
							cliprdr->hmem = GlobalFree(cliprdr->hmem);
						}
						cliprdr_send_format_list(cliprdr);
				}
			}
			if (cliprdr->hwndNextViewer != NULL && cliprdr->hwndNextViewer != hWnd)
				SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam);
			break;

		case WM_RENDERALLFORMATS:
			/* discard all contexts in clipboard */
			if (!OpenClipboard(cliprdr->hwndClipboard))
			{
				DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError());
				break;
			}
			EmptyClipboard();
			CloseClipboard();
			break;

		case WM_RENDERFORMAT:
			if (cliprdr_send_data_request(cliprdr, (UINT32)wParam) != 0)
			{
				DEBUG_CLIPRDR("error: cliprdr_send_data_request failed.");
				break;
			}

			if (SetClipboardData(wParam, cliprdr->hmem) == NULL)
			{
				DEBUG_CLIPRDR("SetClipboardData failed with 0x%x", GetLastError());
				cliprdr->hmem = GlobalFree(cliprdr->hmem);
			}
			/* Note: GlobalFree() is not needed when success */
			break;

		case WM_CLIPBOARDUPDATE:
		case WM_DESTROYCLIPBOARD:
		case WM_ASKCBFORMATNAME:
		case WM_HSCROLLCLIPBOARD:
		case WM_PAINTCLIPBOARD:
		case WM_SIZECLIPBOARD:
		case WM_VSCROLLCLIPBOARD:
		default:
			return DefWindowProc(hWnd, Msg, wParam, lParam);
	}

	return 0;
}
Esempio n. 27
0
////////////////////////////////////////////////////////////////////////////////
// Window procedure for the Desktop window
LRESULT CALLBACK
DesktopWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
#ifndef _X64
	vncDesktop *_this = (vncDesktop*)GetWindowLong(hwnd, GWL_USERDATA);
#else
	vncDesktop *_this = (vncDesktop*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
#endif
	/*#ifdef _DEBUG
										char			szText[256];
										sprintf(szText,"Message %i\n",iMsg );
										OutputDebugString(szText);
										//vnclog.Print(LL_INTERR, VNCLOG("%i  \n"),iMsg);
			#endif*/
	switch (iMsg)
	{
	case WM_CREATE:
		vnclog.Print(LL_INTERR, VNCLOG("wmcreate  \n"));
		break;
	case WM_TIMER:
		if (_this->can_be_hooked)
		{
			if (wParam==100)
			{
					KillTimer(hwnd, 100);
					if (_this->startw8)
					{
						_this->startw8(!_this->multi_monitor);
						vnclog.Print(LL_INTERR, VNCLOG("set W8 hooks OK\n"));
						_this->m_hookinited = TRUE;
					}
					else if (_this->SetHook)
					{
						_this->SetHook(hwnd);
						vnclog.Print(LL_INTERR, VNCLOG("set SC hooks OK\n"));
						_this->m_hookinited = TRUE;
						if (_this->SetKeyboardFilterHooks) _this->SetKeyboardFilterHooks( _this->m_bIsInputDisabledByClient || _this->m_server->LocalInputsDisabled());
						if (_this->SetMouseFilterHooks) _this->SetMouseFilterHooks( _this->m_bIsInputDisabledByClient || _this->m_server->LocalInputsDisabled());
					}
					else if (_this->SetHooks)
					{
						if (!_this->SetHooks(
							GetCurrentThreadId(),
							RFB_SCREEN_UPDATE,
							RFB_COPYRECT_UPDATE,
							RFB_MOUSE_UPDATE, 0
							))
						{
							vnclog.Print(LL_INTERR, VNCLOG("failed to set system hooks\n"));
							// Switch on full screen polling, so they can see something, at least...
							_this->m_server->PollFullScreen(TRUE);
							_this->m_hookinited = FALSE;
						}
						else
						{
							vnclog.Print(LL_INTERR, VNCLOG("set hooks OK\n"));
							_this->m_hookinited = TRUE;
							// Start up the keyboard and mouse filters
							if (_this->SetKeyboardFilterHook) _this->SetKeyboardFilterHook(_this->m_bIsInputDisabledByClient || _this->m_server->LocalInputsDisabled());
							if (_this->SetMouseFilterHook) _this->SetMouseFilterHook(_this->m_bIsInputDisabledByClient || _this->m_server->LocalInputsDisabled());
						}
					}
			}
			else SetEvent(_this->trigger_events[0]);
		}
		break;
	case WM_MOUSESHAPE:
		if (_this->can_be_hooked)
		{
			SetEvent(_this->trigger_events[3]);
		}
		break;
	case WM_HOOKCHANGE:
		if (wParam==1)
			{
				if (_this->m_hookinited==FALSE)
							SetTimer(hwnd,100,1000,NULL);
			}
		else if (wParam==2)
		{
			if (_this->m_hookinited)
				{
					if (_this->SetHook)
					{
						if (_this->SetKeyboardFilterHooks) _this->SetKeyboardFilterHooks( _this->m_bIsInputDisabledByClient || _this->m_server->LocalInputsDisabled());
						if (_this->SetMouseFilterHooks) _this->SetMouseFilterHooks( _this->m_bIsInputDisabledByClient || _this->m_server->LocalInputsDisabled());
					}
					else if (_this->SetHooks)
					{
						if (_this->SetKeyboardFilterHook) _this->SetKeyboardFilterHook( _this->m_bIsInputDisabledByClient || _this->m_server->LocalInputsDisabled());
						if (_this->SetMouseFilterHook) _this->SetMouseFilterHook( _this->m_bIsInputDisabledByClient || _this->m_server->LocalInputsDisabled());
					}
				}
		}
		else if (_this->m_hookinited)
			{
				_this->m_hookinited=FALSE;
				if (_this->stopw8)
				{
					vnclog.Print(LL_INTERR, VNCLOG("unset W8 hooks OK\n"));
					_this->stopw8();
				}
				if (_this->UnSetHook)
				{
					vnclog.Print(LL_INTERR, VNCLOG("unset SC hooks OK\n"));
					_this->UnSetHook(hwnd);
				}
				else if (_this->UnSetHooks)
				{
				if(!_this->UnSetHooks(GetCurrentThreadId()) )
					vnclog.Print(LL_INTERR, VNCLOG("Unsethooks Failed\n"));
				else vnclog.Print(LL_INTERR, VNCLOG("Unsethooks OK\n"));
				}
			}
		return true;

	case WM_QUERYENDSESSION:

		/*if (OSversion()==2)
		{
		if (_this->m_hnextviewer!=NULL) ChangeClipboardChain(hwnd, _this->m_hnextviewer);
		_this->m_hnextviewer=NULL;
		if (_this->m_hookinited)
			{
				_this->m_hookinited=FALSE;
				if (_this->UnSetHook)
				{
					vnclog.Print(LL_INTERR, VNCLOG("unset SC hooks OK\n"));
					_this->UnSetHook(hwnd);
				}
				else if (_this->UnSetHooks)
				{
				if(!_this->UnSetHooks(GetCurrentThreadId()) )
					vnclog.Print(LL_INTERR, VNCLOG("Unsethooks Failed\n"));
				else vnclog.Print(LL_INTERR, VNCLOG("Unsethooks OK\n"));
				}
			}
		vnclog.Print(LL_INTERR, VNCLOG("WM_QUERYENDSESSION\n"));
		PostQuitMessage(0);
		SetEvent(_this->trigger_events[5]);
		}*/
		return DefWindowProc(hwnd, iMsg, wParam, lParam);

	case WM_CLOSE:
		if (_this->m_hnextviewer!=NULL) ChangeClipboardChain(hwnd, _this->m_hnextviewer);
		_this->m_hnextviewer=NULL;
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		KillTimer(hwnd, 100);
		if (_this->m_hnextviewer!=NULL) ChangeClipboardChain(hwnd, _this->m_hnextviewer);
		_this->m_hnextviewer=NULL;
		if (_this->m_hookinited)
			{
				if (_this->stopw8)
				{
					vnclog.Print(LL_INTERR, VNCLOG("unset W8 hooks OK\n"));
					_this->stopw8();
				}
				if (_this->UnSetHook)
				{
					vnclog.Print(LL_INTERR, VNCLOG("unset SC hooks OK\n"));
					_this->UnSetHook(hwnd);
				}
				else if (_this->UnSetHooks)
				{
				if(!_this->UnSetHooks(GetCurrentThreadId()) )
					vnclog.Print(LL_INTERR, VNCLOG("Unsethooks Failed\n"));
				else vnclog.Print(LL_INTERR, VNCLOG("Unsethooks OK\n"));
				}
				_this->m_hookinited=FALSE;
			}
		vnclog.Print(LL_INTERR, VNCLOG("WM_DESTROY\n"));
		break;
	///ddihook
	case WM_SYSCOMMAND:
		// User has clicked an item on the tray menu
		switch (wParam)
		{
			case SC_MONITORPOWER:
				vnclog.Print(LL_INTINFO, VNCLOG("Monitor22 %i\n"),lParam);
		}
		vnclog.Print(LL_INTINFO, VNCLOG("Monitor3 %i %i\n"),wParam,lParam);
		return DefWindowProc(hwnd, iMsg, wParam, lParam);
	case WM_POWER:
	case WM_POWERBROADCAST:
		// User has clicked an item on the tray menu
		switch (wParam)
		{
			case SC_MONITORPOWER:
				vnclog.Print(LL_INTINFO, VNCLOG("Monitor222 %i\n"),lParam);
		}
		vnclog.Print(LL_INTINFO, VNCLOG("Power3 %i %i\n"),wParam,lParam);
		return DefWindowProc(hwnd, iMsg, wParam, lParam);

	case WM_COPYDATA:
        {
			PCOPYDATASTRUCT pMyCDS = (PCOPYDATASTRUCT) lParam;
			if (pMyCDS->dwData==112233)
			{
					DWORD mysize=pMyCDS->cbData;
					char mytext[1024];
					char *myptr;
					char split[4][6];
					strcpy(mytext,(LPCSTR)pMyCDS->lpData);
					myptr=mytext;
					for (DWORD j =0; j<(mysize/20);j++)
					{
						for (int i=0;i<4;i++)
							{
								strcpy(split[i],"     ");
								strncpy(split[i],myptr,4);
								myptr=myptr+5;
							}
						_this->QueueRect(rfb::Rect(atoi(split[0]), atoi(split[1]), atoi(split[2]), atoi(split[3])));
					}
			}
			//vnclog.Print(LL_INTINFO, VNCLOG("copydata\n"));
        }
			return 0;

	// GENERAL

	case WM_DISPLAYCHANGE:
		// The display resolution is changing
		// We must kick off any clients since their screen size will be wrong
		// WE change the clients screensize, if they support it.
		vnclog.Print(LL_INTERR, VNCLOG("WM_DISPLAYCHANGE\n"));
		// We First check if the Resolution changed is caused by a temp resolution switch
		// For a temp resolution we don't use the driver, to fix the mirror driver
		// to the new change, a resolution switch is needed, preventing screensaver locking.

		if (_this->m_videodriver != NULL) //Video driver active
		{
			if (!_this->m_videodriver->blocked)
			{
				_this->m_displaychanged = TRUE;
				_this->m_hookdriver=true;
				_this->m_videodriver->blocked=true;
				vnclog.Print(LL_INTERR, VNCLOG("Resolution switch detected, driver active\n"));
			}
			else
			{
				//Remove display change, cause by driver activation
				_this->m_videodriver->blocked=false;
				vnclog.Print(LL_INTERR, VNCLOG("Resolution switch by driver activation removed\n"));
			}
		}
		else
		{
				_this->m_displaychanged = TRUE;
				_this->m_hookdriver=true;
				vnclog.Print(LL_INTERR, VNCLOG("Resolution switch detected, driver NOT active\n"));
		}
		return 0;

	case WM_SYSCOLORCHANGE:
	case WM_PALETTECHANGED:
		if (!_this->m_displaychanged)
		{
		// The palette colours have changed, so tell the server

		// Get the system palette
            // better to use the wrong colors than close the connection
		_this->SetPalette();

		// Update any palette-based clients, too
		//set to flase to avoid deadlock
		_this->m_server->UpdatePalette(false);
		}
		return 0;

		// CLIPBOARD MESSAGES

	case WM_CHANGECBCHAIN:
		// The clipboard chain has changed - check our nextviewer handle
		if ((HWND)wParam == _this->m_hnextviewer)
			_this->m_hnextviewer = (HWND)lParam;
		else
			if (_this->m_hnextviewer != NULL) {
				// adzm - 2010-07 - Fix clipboard hangs
				// use SendNotifyMessage instead of SendMessage so misbehaving or hung applications
				// won't cause our thread to hang.
				SendNotifyMessage(_this->m_hnextviewer,
							WM_CHANGECBCHAIN,
							wParam, lParam);
			}

		return 0;

	case WM_DRAWCLIPBOARD:
		// adzm - 2010-07 - Fix clipboard hangs
		if (_this->can_be_hooked && !_this->m_settingClipboardViewer)
		{
			// The clipboard contents have changed
			if((GetClipboardOwner() != _this->Window()) &&
				//_this->m_initialClipBoardSeen &&
				_this->m_clipboard_active && !_this->m_server->IsThereFileTransBusy())
			{
				// adzm - 2010-07 - Extended clipboard
				{
					// only need a window when setting clipboard data
					omni_mutex_lock l(_this->m_update_lock);
					_this->m_server->UpdateClipTextEx(NULL);
				}
				/*
				LPSTR cliptext = NULL;

				// Open the clipboard
				if (OpenClipboard(_this->Window()))
				{
					// Get the clipboard data
					HGLOBAL cliphandle = GetClipboardData(CF_TEXT);
					if (cliphandle != NULL)
					{
						LPSTR clipdata = (LPSTR) GlobalLock(cliphandle);

						// Copy it into a new buffer
						if (clipdata == NULL)
							cliptext = NULL;
						else
							cliptext = _strdup(clipdata);

						// Release the buffer and close the clipboard
						GlobalUnlock(cliphandle);
					}

					CloseClipboard();
				}

				if (cliptext != NULL)
				{
					int cliplen = strlen(cliptext);
					LPSTR unixtext = (char *)malloc(cliplen+1);

					// Replace CR-LF with LF - never send CR-LF on the wire,
					// since Unix won't like it
					int unixpos=0;
					for (int x=0; x<cliplen; x++)
					{
						if (cliptext[x] != '\x0d')
						{
							unixtext[unixpos] = cliptext[x];
							unixpos++;
						}
					}
					unixtext[unixpos] = 0;

					// Free the clip text
					free(cliptext);
					cliptext = NULL;

					// Now send the unix text to the server
					omni_mutex_lock l(_this->m_update_lock);
					_this->m_server->UpdateClipText(unixtext);

					free(unixtext);
				}
				*/
			}

			//_this->m_initialClipBoardSeen = TRUE;
		}

		if (_this->m_hnextviewer != NULL)
		{
			// adzm - 2010-07 - Fix clipboard hangs
			// Pass the message to the next window in clipboard viewer chain.

			// use SendNotifyMessage instead of SendMessage so misbehaving or hung applications
			// won't cause our thread to hang.
			return SendNotifyMessage(_this->m_hnextviewer, WM_DRAWCLIPBOARD, wParam, lParam);
		}

		return 0;

	default:
		return DefWindowProc(hwnd, iMsg, wParam, lParam);
	}
	return 0;
}
Esempio n. 28
0
static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    AssertPtr(pCtx);

    LRESULT rc = 0;

    switch (msg)
    {
        case WM_CLIPBOARDUPDATE:
        {
            Log(("WM_CLIPBOARDUPDATE\n"));

            if (GetClipboardOwner() != hwnd)
            {
                /* Clipboard was updated by another application. */
                vboxClipboardChanged(pCtx);
            }
        } break;

        case WM_CHANGECBCHAIN:
        {
            if (vboxClipboardIsNewAPI(pCtx))
            {
                rc = DefWindowProc(hwnd, msg, wParam, lParam);
                break;
            }

            HWND hwndRemoved = (HWND)wParam;
            HWND hwndNext    = (HWND)lParam;

            LogFlowFunc(("WM_CHANGECBCHAIN: hwndRemoved %p, hwndNext %p, hwnd %p\n", hwndRemoved, hwndNext, pCtx->hwnd));

            if (hwndRemoved == pCtx->hwndNextInChain)
            {
                /* The window that was next to our in the chain is being removed.
                 * Relink to the new next window. */
                pCtx->hwndNextInChain = hwndNext;
            }
            else
            {
                if (pCtx->hwndNextInChain)
                {
                    /* Pass the message further. */
                    DWORD_PTR dwResult;
                    rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
                    if (!rc)
                        rc = (LRESULT) dwResult;
                }
            }
        } break;

        case WM_DRAWCLIPBOARD:
        {
            LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pCtx->hwnd));

            if (GetClipboardOwner() != hwnd)
            {
                /* Clipboard was updated by another application. */
                /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */
                int vboxrc = vboxClipboardChanged(pCtx);
                if (RT_FAILURE(vboxrc))
                    LogFlowFunc(("vboxClipboardChanged failed, rc = %Rrc\n", vboxrc));
            }

            if (pCtx->hwndNextInChain)
            {
                /* Pass the message to next windows in the clipboard chain. */
                SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, NULL);
            }
        } break;

        case WM_TIMER:
        {
            if (vboxClipboardIsNewAPI(pCtx))
                break;

            HWND hViewer = GetClipboardViewer();

            /* Re-register ourselves in the clipboard chain if our last ping
             * timed out or there seems to be no valid chain. */
            if (!hViewer || pCtx->fCBChainPingInProcess)
            {
                vboxClipboardRemoveFromCBChain(pCtx);
                vboxClipboardAddToCBChain(pCtx);
            }
            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
             * processed by ourselves to the chain. */
            pCtx->fCBChainPingInProcess = TRUE;
            hViewer = GetClipboardViewer();
            if (hViewer)
                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR)pCtx);
        } break;

        case WM_CLOSE:
        {
            /* Do nothing. Ignore the message. */
        } break;

        case WM_RENDERFORMAT:
        {
            /* Insert the requested clipboard format data into the clipboard. */
            uint32_t u32Format = 0;
            UINT format = (UINT)wParam;

            LogFlowFunc(("WM_RENDERFORMAT, format = %x\n", format));
            switch (format)
            {
                case CF_UNICODETEXT:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
                    break;

                case CF_DIB:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
                    break;

                default:
                    if (format >= 0xC000)
                    {
                        TCHAR szFormatName[256];

                        int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
                        if (cActual)
                        {
                            if (strcmp (szFormatName, "HTML Format") == 0)
                            {
                                u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
                            }
                        }
                    }
                    break;
            }

            if (u32Format == 0)
            {
                /* Unsupported clipboard format is requested. */
                LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format));
                EmptyClipboard();
            }
            else
            {
                const uint32_t cbPrealloc = 4096; /** @todo r=andy Make it dynamic for supporting larger text buffers! */
                uint32_t cb = 0;

                /* Preallocate a buffer, most of small text transfers will fit into it. */
                HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
                LogFlowFunc(("Preallocated handle hMem = %p\n", hMem));

                if (hMem)
                {
                    void *pMem = GlobalLock(hMem);
                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                    if (pMem)
                    {
                        /* Read the host data to the preallocated buffer. */
                        int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cbPrealloc, &cb);
                        LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n",  vboxrc));

                        if (RT_SUCCESS(vboxrc))
                        {
                            if (cb == 0)
                            {
                                /* 0 bytes returned means the clipboard is empty.
                                 * Deallocate the memory and set hMem to NULL to get to
                                 * the clipboard empty code path. */
                                GlobalUnlock(hMem);
                                GlobalFree(hMem);
                                hMem = NULL;
                            }
                            else if (cb > cbPrealloc)
                            {
                                GlobalUnlock(hMem);

                                /* The preallocated buffer is too small, adjust the size. */
                                hMem = GlobalReAlloc(hMem, cb, 0);
                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                                if (hMem)
                                {
                                    pMem = GlobalLock(hMem);
                                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                                    if (pMem)
                                    {
                                        /* Read the host data to the preallocated buffer. */
                                        uint32_t cbNew = 0;
                                        vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cb, &cbNew);
                                        LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew));

                                        if (RT_SUCCESS (vboxrc) && cbNew <= cb)
                                        {
                                            cb = cbNew;
                                        }
                                        else
                                        {
                                            GlobalUnlock(hMem);
                                            GlobalFree(hMem);
                                            hMem = NULL;
                                        }
                                    }
                                    else
                                    {
                                        GlobalFree(hMem);
                                        hMem = NULL;
                                    }
                                }
                            }

                            if (hMem)
                            {
                                /* pMem is the address of the data. cb is the size of returned data. */
                                /* Verify the size of returned text, the memory block for clipboard
                                 * must have the exact string size.
                                 */
                                if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                                {
                                    size_t cbActual = 0;
                                    HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual);
                                    if (FAILED (hrc))
                                    {
                                        /* Discard invalid data. */
                                        GlobalUnlock(hMem);
                                        GlobalFree(hMem);
                                        hMem = NULL;
                                    }
                                    else
                                    {
                                        /* cbActual is the number of bytes, excluding those used
                                         * for the terminating null character.
                                         */
                                        cb = (uint32_t)(cbActual + 2);
                                    }
                                }
                            }

                            if (hMem)
                            {
                                GlobalUnlock(hMem);

                                hMem = GlobalReAlloc(hMem, cb, 0);
                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                                if (hMem)
                                {
                                    /* 'hMem' contains the host clipboard data.
                                     * size is 'cb' and format is 'format'. */
                                    HANDLE hClip = SetClipboardData(format, hMem);
                                    LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));

                                    if (hClip)
                                    {
                                        /* The hMem ownership has gone to the system. Finish the processing. */
                                        break;
                                    }

                                    /* Cleanup follows. */
                                }
                            }
                        }
                        if (hMem)
                            GlobalUnlock(hMem);
                    }
                    if (hMem)
                        GlobalFree(hMem);
                }

                /* Something went wrong. */
                EmptyClipboard();
            }
        } break;

        case WM_RENDERALLFORMATS:
        {
            /* Do nothing. The clipboard formats will be unavailable now, because the
             * windows is to be destroyed and therefore the guest side becomes inactive.
             */
            int vboxrc = vboxOpenClipboard(hwnd);
            if (RT_SUCCESS(vboxrc))
            {
                EmptyClipboard();
                CloseClipboard();
            }
            else
            {
                LogFlowFunc(("WM_RENDERALLFORMATS: Failed to open clipboard! rc: %Rrc\n", vboxrc));
            }
        } break;

        case WM_USER:
        {
            /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
            uint32_t u32Formats = (uint32_t)lParam;

            int vboxrc = vboxOpenClipboard(hwnd);
            if (RT_SUCCESS(vboxrc))
            {
                EmptyClipboard();

                HANDLE hClip = NULL;

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                {
                    LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n"));
                    hClip = SetClipboardData(CF_UNICODETEXT, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                {
                    LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
                    hClip = SetClipboardData(CF_DIB, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
                {
                    UINT format = RegisterClipboardFormat ("HTML Format");
                    LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format));
                    if (format != 0)
                    {
                        hClip = SetClipboardData(format, NULL);
                    }
                }

                CloseClipboard();
                LogFlowFunc(("WM_USER: hClip = %p, err = %ld\n", hClip, GetLastError ()));
            }
            else
            {
                LogFlowFunc(("WM_USER: Failed to open clipboard! error = %Rrc\n", vboxrc));
            }
        } break;

        case WM_USER + 1:
        {
            /* Send data in the specified format to the host. */
            uint32_t u32Formats = (uint32_t)lParam;
            HANDLE hClip = NULL;

            int vboxrc = vboxOpenClipboard(hwnd);
            if (RT_SUCCESS(vboxrc))
            {
                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                {
                    hClip = GetClipboardData(CF_DIB);

                    if (hClip != NULL)
                    {
                        LPVOID lp = GlobalLock(hClip);
                        if (lp != NULL)
                        {
                            LogFlowFunc(("WM_USER + 1: CF_DIB\n"));
                            vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP,
                                                              lp, GlobalSize(hClip));
                            GlobalUnlock(hClip);
                        }
                        else
                        {
                            hClip = NULL;
                        }
                    }
                }
                else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                {
                    hClip = GetClipboardData(CF_UNICODETEXT);

                    if (hClip != NULL)
                    {
                        LPWSTR uniString = (LPWSTR)GlobalLock(hClip);

                        if (uniString != NULL)
                        {
                            LogFlowFunc(("WM_USER + 1: CF_UNICODETEXT\n"));
                            vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,
                                                              uniString, (lstrlenW(uniString) + 1) * 2);
                            GlobalUnlock(hClip);
                        }
                        else
                        {
                            hClip = NULL;
                        }
                    }
                }
                else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
                {
                    UINT format = RegisterClipboardFormat ("HTML Format");
                    if (format != 0)
                    {
                        hClip = GetClipboardData(format);
                        if (hClip != NULL)
                        {
                            LPVOID lp = GlobalLock(hClip);

                            if (lp != NULL)
                            {
                                LogFlowFunc(("WM_USER + 1: CF_HTML\n"));
                                vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML,
                                                                  lp, GlobalSize(hClip));
                                GlobalUnlock(hClip);
                            }
                            else
                            {
                                hClip = NULL;
                            }
                        }
                    }
                }

                CloseClipboard();
            }
            else
            {
                LogFlowFunc(("WM_USER: Failed to open clipboard! rc: %Rrc\n", vboxrc));
            }

            if (hClip == NULL)
            {
                /* Requested clipboard format is not available, send empty data. */
                VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0);
            }
        } break;

        case WM_DESTROY:
        {
            vboxClipboardRemoveFromCBChain(pCtx);
            if (pCtx->timerRefresh)
                KillTimer(pCtx->hwnd, 0);
            /*
             * don't need to call PostQuitMessage cause
             * the VBoxTray already finished a message loop
             */
        } break;

        default:
        {
            rc = DefWindowProc(hwnd, msg, wParam, lParam);
        }
    }

#ifndef DEBUG_andy
    LogFlowFunc(("vboxClipboardProcessMsg returned with rc = %ld\n", rc));
#endif
    return rc;
}
Esempio n. 29
0
int
scrap_lost_win (void)
{
    return (GetClipboardOwner () != _sdlwindow);
}
void *
winClipboardProc(void *pvNotUsed)
{
    Atom atomClipboard, atomClipboardManager;
    int iReturn;
    HWND hwnd = NULL;
    int iConnectionNumber = 0;

#ifdef HAS_DEVWINDOWS
    int fdMessageQueue = 0;
#else
    struct timeval tvTimeout;
#endif
    fd_set fdsRead;
    int iMaxDescriptor;
    Display *pDisplay = NULL;
    Window iWindow = None;
    int iRetries;
    Bool fUseUnicode;
    char szDisplay[512];
    int iSelectError;

    winDebug("winClipboardProc - Hello\n");
    ++clipboardRestarts;

    /* Do we use Unicode clipboard? */
    fUseUnicode = g_fUnicodeClipboard;

    /* Save the Unicode support flag in a global */
    g_fUseUnicode = fUseUnicode;

    /* Allow multiple threads to access Xlib */
    if (XInitThreads() == 0) {
        ErrorF("winClipboardProc - XInitThreads failed.\n");
        goto winClipboardProc_Exit;
    }

    /* See if X supports the current locale */
    if (XSupportsLocale() == False) {
        ErrorF("winClipboardProc - Warning: Locale not supported by X.\n");
    }

    /* Set error handler */
    XSetErrorHandler(winClipboardErrorHandler);
    g_winClipboardProcThread = pthread_self();
    g_winClipboardOldIOErrorHandler =
        XSetIOErrorHandler(winClipboardIOErrorHandler);

    /* Set jump point for Error exits */
    iReturn = setjmp(g_jmpEntry);

    /* Check if we should continue operations */
    if (iReturn != WIN_JMP_ERROR_IO && iReturn != WIN_JMP_OKAY) {
        /* setjmp returned an unknown value, exit */
        ErrorF("winClipboardProc - setjmp returned: %d exiting\n", iReturn);
        goto winClipboardProc_Exit;
    }
    else if (iReturn == WIN_JMP_ERROR_IO) {
        /* TODO: Cleanup the Win32 window and free any allocated memory */
        ErrorF("winClipboardProc - setjmp returned for IO Error Handler.\n");
        pthread_exit(NULL);
    }

    /* Use our generated cookie for authentication */
    winSetAuthorization();

    /* Initialize retry count */
    iRetries = 0;

    /* Setup the display connection string x */
    /*
     * NOTE: Always connect to screen 0 since we require that screen
     * numbers start at 0 and increase without gaps.  We only need
     * to connect to one screen on the display to get events
     * for all screens on the display.  That is why there is only
     * one clipboard client thread.
     */
    snprintf(szDisplay, 512, "127.0.0.1:%s.0", display);

    /* Print the display connection string */
    ErrorF("winClipboardProc - DISPLAY=%s\n", szDisplay);

    /* Open the X display */
    do {
        pDisplay = XOpenDisplay(szDisplay);
        if (pDisplay == NULL) {
            ErrorF("winClipboardProc - Could not open display, "
                   "try: %d, sleeping: %d\n", iRetries + 1, WIN_CONNECT_DELAY);
            ++iRetries;
            sleep(WIN_CONNECT_DELAY);
            continue;
        }
        else
            break;
    }
    while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);

    /* Make sure that the display opened */
    if (pDisplay == NULL) {
        ErrorF("winClipboardProc - Failed opening the display, giving up\n");
        goto winClipboardProc_Done;
    }

    /* Save the display in the screen privates */
    g_pClipboardDisplay = pDisplay;

    ErrorF("winClipboardProc - XOpenDisplay () returned and "
           "successfully opened the display.\n");

    /* Get our connection number */
    iConnectionNumber = ConnectionNumber(pDisplay);

#ifdef HAS_DEVWINDOWS
    /* Open a file descriptor for the windows message queue */
    fdMessageQueue = open(WIN_MSG_QUEUE_FNAME, O_RDONLY);
    if (fdMessageQueue == -1) {
        ErrorF("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME);
        goto winClipboardProc_Done;
    }

    /* Find max of our file descriptors */
    iMaxDescriptor = max(fdMessageQueue, iConnectionNumber) + 1;
#else
    iMaxDescriptor = iConnectionNumber + 1;
#endif

    /* Create atoms */
    atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False);
    atomClipboardManager = XInternAtom(pDisplay, "CLIPBOARD_MANAGER", False);

    /* Create a messaging window */
    iWindow = XCreateSimpleWindow(pDisplay,
                                  DefaultRootWindow(pDisplay),
                                  1, 1,
                                  500, 500,
                                  0,
                                  BlackPixel(pDisplay, 0),
                                  BlackPixel(pDisplay, 0));
    if (iWindow == 0) {
        ErrorF("winClipboardProc - Could not create an X window.\n");
        goto winClipboardProc_Done;
    }

    XStoreName(pDisplay, iWindow, "xwinclip");

    /* Select event types to watch */
    if (XSelectInput(pDisplay, iWindow, PropertyChangeMask) == BadWindow)
        ErrorF("winClipboardProc - XSelectInput generated BadWindow "
               "on messaging window\n");

    /* Save the window in the screen privates */
    g_iClipboardWindow = iWindow;

    /* Create Windows messaging window */
    hwnd = winClipboardCreateMessagingWindow();

    /* Save copy of HWND in screen privates */
    g_hwndClipboard = hwnd;

    /* Assert ownership of selections if Win32 clipboard is owned */
    if (NULL != GetClipboardOwner()) {
        /* PRIMARY */
        iReturn = XSetSelectionOwner(pDisplay, XA_PRIMARY,
                                     iWindow, CurrentTime);
        if (iReturn == BadAtom || iReturn == BadWindow ||
            XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) {
            ErrorF("winClipboardProc - Could not set PRIMARY owner\n");
            goto winClipboardProc_Done;
        }

        /* CLIPBOARD */
        iReturn = XSetSelectionOwner(pDisplay, atomClipboard,
                                     iWindow, CurrentTime);
        if (iReturn == BadAtom || iReturn == BadWindow ||
            XGetSelectionOwner(pDisplay, atomClipboard) != iWindow) {
            ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n");
            goto winClipboardProc_Done;
        }
    }

    /* Pre-flush X events */
    /* 
     * NOTE: Apparently you'll freeze if you don't do this,
     *       because there may be events in local data structures
     *       already.
     */
    winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode);

    /* Pre-flush Windows messages */
    if (!winClipboardFlushWindowsMessageQueue(hwnd))
        return 0;

    /* Signal that the clipboard client has started */
    g_fClipboardStarted = TRUE;

    /* Loop for X events */
    while (1) {
        /* Setup the file descriptor set */
        /*
         * NOTE: You have to do this before every call to select
         *       because select modifies the mask to indicate
         *       which descriptors are ready.
         */
        FD_ZERO(&fdsRead);
        FD_SET(iConnectionNumber, &fdsRead);
#ifdef HAS_DEVWINDOWS
        FD_SET(fdMessageQueue, &fdsRead);
#else
        tvTimeout.tv_sec = 0;
        tvTimeout.tv_usec = 100;
#endif

        /* Wait for a Windows event or an X event */
        iReturn = select(iMaxDescriptor,        /* Highest fds number */
                         &fdsRead,      /* Read mask */
                         NULL,  /* No write mask */
                         NULL,  /* No exception mask */
#ifdef HAS_DEVWINDOWS
                         NULL   /* No timeout */
#else
                         &tvTimeout     /* Set timeout */
#endif
            );

#ifndef HAS_WINSOCK
        iSelectError = errno;
#else
        iSelectError = WSAGetLastError();
#endif

        if (iReturn < 0) {
#ifndef HAS_WINSOCK
            if (iSelectError == EINTR)
#else
            if (iSelectError == WSAEINTR)
#endif
                continue;

            ErrorF("winClipboardProc - Call to select () failed: %d.  "
                   "Bailing.\n", iReturn);
            break;
        }

        /* Branch on which descriptor became active */
        if (FD_ISSET(iConnectionNumber, &fdsRead)) {
            /* Process X events */
            /* Exit when we see that server is shutting down */
            iReturn = winClipboardFlushXEvents(hwnd,
                                               iWindow, pDisplay, fUseUnicode);
            if (WIN_XEVENTS_SHUTDOWN == iReturn) {
                ErrorF("winClipboardProc - winClipboardFlushXEvents "
                       "trapped shutdown event, exiting main loop.\n");
                break;
            }
        }

#ifdef HAS_DEVWINDOWS
        /* Check for Windows event ready */
        if (FD_ISSET(fdMessageQueue, &fdsRead))
#else
        if (1)
#endif
        {
            /* Process Windows messages */
            if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
                ErrorF("winClipboardProc - "
                       "winClipboardFlushWindowsMessageQueue trapped "
                       "WM_QUIT message, exiting main loop.\n");
                break;
            }
        }
    }

 winClipboardProc_Exit:
    /* disable the clipboard, which means the thread will die */
    g_fClipboard = FALSE;

 winClipboardProc_Done:
    /* Close our Windows window */
    if (g_hwndClipboard) {
        /* Destroy the Window window (hwnd) */
        winDebug("winClipboardProc - Destroy Windows window\n");
        PostMessage(g_hwndClipboard, WM_DESTROY, 0, 0);
        winClipboardFlushWindowsMessageQueue(g_hwndClipboard);
    }

    /* Close our X window */
    if (pDisplay && iWindow) {
        iReturn = XDestroyWindow(pDisplay, iWindow);
        if (iReturn == BadWindow)
            ErrorF("winClipboardProc - XDestroyWindow returned BadWindow.\n");
        else
            ErrorF("winClipboardProc - XDestroyWindow succeeded.\n");
    }

#ifdef HAS_DEVWINDOWS
    /* Close our Win32 message handle */
    if (fdMessageQueue)
        close(fdMessageQueue);
#endif

#if 0
    /*
     * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26.  The
     * XSync and XSelectInput calls did not help.
     */

    /* Discard any remaining events */
    XSync(pDisplay, TRUE);

    /* Select event types to watch */
    XSelectInput(pDisplay, DefaultRootWindow(pDisplay), None);

    /* Close our X display */
    if (pDisplay) {
        XCloseDisplay(pDisplay);
    }
#endif

    /* global clipboard variable reset */
    g_fClipboardLaunched = FALSE;
    g_fClipboardStarted = FALSE;
    g_iClipboardWindow = None;
    g_pClipboardDisplay = NULL;
    g_hwndClipboard = NULL;

    /* checking if we need to restart */
    if (clipboardRestarts >= WIN_CLIPBOARD_RETRIES) {
        /* terminates clipboard thread but the main server still lives */
        ErrorF
            ("winClipboardProc - the clipboard thread has restarted %d times and seems to be unstable, disabling clipboard integration\n",
             clipboardRestarts);
        g_fClipboard = FALSE;
        return;
    }

    if (g_fClipboard) {
        sleep(WIN_CLIPBOARD_DELAY);
        ErrorF("winClipboardProc - trying to restart clipboard thread \n");
        /* Create the clipboard client thread */
        if (!winInitClipboard()) {
            ErrorF("winClipboardProc - winClipboardInit failed.\n");
            return;
        }

        winDebug("winClipboardProc - winInitClipboard returned.\n");
        /* Flag that clipboard client has been launched */
        g_fClipboardLaunched = TRUE;
    }
    else {
        ErrorF("winClipboardProc - Clipboard disabled  - Exit from server \n");
        /* clipboard thread has exited, stop server as well */
        kill(getpid(), SIGTERM);
    }

    return NULL;
}