⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clipboard.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * COPYRIGHT:        See COPYING in the top level directory
 * PROJECT:          ReactOS kernel
 * PURPOSE:          Clipboard routines
 * FILE:             subsys/win32k/ntuser/clipboard.c
 * PROGRAMER:        Filip Navara <xnavara@volny.cz>
 *                   Pablo Borobia <pborobia@gmail.com>
 */

#include <w32k.h>

#define NDEBUG
#include <debug.h>

#define DATA_DELAYED_RENDER  0
#define DATA_SYNTHESIZED_RENDER -1

#define USE_WINSTA \
    PWINSTATION_OBJECT WinStaObj; \
    WinStaObj = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation;

#define WINSTA_ClipboardThread WinStaObj->Clipboard->ClipboardThread
#define WINSTA_ClipboardOwnerThread WinStaObj->Clipboard->ClipboardOwnerThread
#define WINSTA_ClipboardWindow WinStaObj->Clipboard->ClipboardWindow
#define WINSTA_ClipboardViewerWindow WinStaObj->Clipboard->ClipboardViewerWindow
#define WINSTA_ClipboardOwnerWindow WinStaObj->Clipboard->ClipboardOwnerWindow
#define WINSTA_sendDrawClipboardMsg WinStaObj->Clipboard->sendDrawClipboardMsg
#define WINSTA_recentlySetClipboard WinStaObj->Clipboard->recentlySetClipboard
#define WINSTA_delayedRender WinStaObj->Clipboard->delayedRender
#define WINSTA_lastEnumClipboardFormats WinStaObj->Clipboard->lastEnumClipboardFormats
#define WINSTA_ClipboardSequenceNumber WinStaObj->Clipboard->ClipboardSequenceNumber
#define WINSTA_WindowsChain WinStaObj->Clipboard->WindowsChain
#define WINSTA_ClipboardData WinStaObj->Clipboard->ClipboardData
#define WINSTA_synthesizedData WinStaObj->Clipboard->synthesizedData
#define WINSTA_synthesizedDataSize WinStaObj->Clipboard->synthesizedDataSize

PW32THREAD      ClipboardThread;
PW32THREAD      ClipboardOwnerThread;
PWINDOW_OBJECT  ClipboardWindow;
PWINDOW_OBJECT  ClipboardViewerWindow;
PWINDOW_OBJECT  ClipboardOwnerWindow;
BOOL            sendDrawClipboardMsg;
BOOL            recentlySetClipboard;
BOOL            delayedRender;
UINT            lastEnumClipboardFormats;
DWORD           ClipboardSequenceNumber = 0;

PCLIPBOARDCHAINELEMENT WindowsChain = NULL;
PCLIPBOARDELEMENT      ClipboardData = NULL;

PCHAR synthesizedData;
DWORD synthesizedDataSize;


/*==============================================================*/

/* return the pointer to the prev window of the finded window,
   if NULL does not exists in the chain */
PCLIPBOARDCHAINELEMENT FASTCALL
IntIsWindowInChain(PWINDOW_OBJECT window)
{
    PCLIPBOARDCHAINELEMENT wce = WindowsChain;

    while (wce)
    {
        if (wce->window == window)
        {
            break;
        }
        wce = wce->next;
    }

    return wce;
}

VOID FASTCALL printChain()
{
    /*test*/
    PCLIPBOARDCHAINELEMENT wce2 = WindowsChain;
    while (wce2)
    {
        DPRINT1("chain: %p\n", wce2->window->hSelf);
        wce2 = wce2->next;
    }
}

/* the new window always have to be the first in the chain */
PCLIPBOARDCHAINELEMENT FASTCALL
IntAddWindowToChain(PWINDOW_OBJECT window)
{
    PCLIPBOARDCHAINELEMENT wce = NULL;

    if (!IntIsWindowInChain(window))
    {
        wce = WindowsChain;

        wce = ExAllocatePool(PagedPool, sizeof(CLIPBOARDCHAINELEMENT));
        if (wce == NULL)
        {
            SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
            goto exit_addChain;
        }

        wce->window = window;
        wce->next = WindowsChain;

        WindowsChain = wce;

        //printChain();
    }
exit_addChain:

    /* return the next window to beremoved later */
    return wce;
}

PCLIPBOARDCHAINELEMENT FASTCALL
IntRemoveWindowFromChain(PWINDOW_OBJECT window)
{
    PCLIPBOARDCHAINELEMENT wce = WindowsChain;
	PCLIPBOARDCHAINELEMENT *link = &WindowsChain;

    if (IntIsWindowInChain(window))
    {
        while (wce != NULL)
        {
            if (wce->window == window)
            {
                *link = wce->next;
                break;
            }

            link = &wce->next;
            wce = wce->next;
        }

        //printChain();

        return wce;
    }
    else
    {
        return NULL;
    }
}


/*==============================================================*/
/* if format exists, returns a non zero value (pointing to format object) */
PCLIPBOARDELEMENT FASTCALL
intIsFormatAvailable(format)
{
    PCLIPBOARDELEMENT ret = NULL;
    PCLIPBOARDELEMENT ce = ClipboardData;

    while(ce)
    {
	    if (ce->format == format)
	    {
	        ret = ce;
	        break;
	    }
	    ce = ce->next;
    }
    return ret;
}

/* counts how many distinct format were are in the clipboard */
DWORD FASTCALL
IntCountClipboardFormats()
{
    DWORD ret = 0;
    PCLIPBOARDELEMENT ce = ClipboardData;

    while(ce)
    {
        ret++;
	    ce = ce->next;
    }
    return ret;
}

/* adds a new format and data to the clipboard */
PCLIPBOARDELEMENT FASTCALL
intAddFormatedData(UINT format, HANDLE hData, DWORD size)
{
    PCLIPBOARDELEMENT ce = NULL;

    ce = ExAllocatePool(PagedPool, sizeof(CLIPBOARDELEMENT));
    if (ce == NULL)
    {
        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
    }
    else
    {
        ce->format = format;
        ce->size = size;
        ce->hData = hData;
        ce->next = ClipboardData;

        ClipboardData = ce;

        IntIncrementSequenceNumber();
    }

    return ce;
}

/* removes a format and its data from the clipboard */
BOOL FASTCALL
intRemoveFormatedData(UINT format)
{
    BOOL ret = FALSE;
    PCLIPBOARDELEMENT ce = ClipboardData;
    PCLIPBOARDELEMENT *link = &ClipboardData;

    if (intIsFormatAvailable(format))
    {
        while (ce != NULL)
        {
            if (ce->format == format)
            {
                *link = ce->next;
                break;
            }

            link = &ce->next;
            ce = ce->next;
        }

        if (ce->hData)
        {
            ExFreePool(ce->hData);
        }
        ExFreePool(ce);
        ret = TRUE;
    }

    return ret;
}

VOID FASTCALL
IntEmptyClipboardData()
{
    PCLIPBOARDELEMENT ce = ClipboardData;
    PCLIPBOARDELEMENT tmp;

    while(ce)
    {
        tmp = ce->next;
        ExFreePool(ce->hData);
	    ExFreePool(ce);
	    ce = tmp;
    }

    ClipboardData = NULL;
}

/*==============================================================*/

HANDLE FASTCALL
renderBITMAPfromDIB(LPBYTE hDIB)
{
    HDC hdc;
    HBITMAP hbitmap;
    unsigned int offset;
    BITMAPINFOHEADER *ih;

    //hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE);
    hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE);

    ih = (BITMAPINFOHEADER *)hDIB;

    offset = sizeof(BITMAPINFOHEADER) + ((ih->biBitCount <= 8) ? (sizeof(RGBQUAD) * (1 << ih->biBitCount)) : 0);

    hbitmap = NtGdiCreateDIBitmap(hdc, ih, CBM_INIT, (LPBYTE)ih + offset, (LPBITMAPINFO)ih, DIB_RGB_COLORS);

    //UserReleaseDC(NULL, hdc, FALSE);
    UserReleaseDC(ClipboardWindow, hdc, FALSE);

    return hbitmap;
}

BOOL FASTCALL
canSinthesize(UINT format)
{
    BOOL ret = FALSE;

    switch(format)
    {
        case CF_BITMAP:
        case CF_METAFILEPICT:
            ret = TRUE;
    }

    return ret;
}

/* returns the size of the sinthesized data */
DWORD FASTCALL
synthesizeData(UINT format)
{
    DWORD ret = 0;

    synthesizedData = NULL;
    synthesizedDataSize = 0;

    if (!canSinthesize(format))
    {
        return 0;
    }

    switch (format)
    {
        case CF_BITMAP:
        {
            break;
        }

        case CF_METAFILEPICT:
        {
            break;
        }
    }

    ret = 1;

    return ret;
}

VOID FASTCALL
freeSynthesizedData()
{
    ExFreePool(synthesizedData);
}

/*==============================================================*/

BOOL FASTCALL
intIsClipboardOpenByMe()
{
    /* check if we open the clipboard */
    if (ClipboardThread && ClipboardThread == PsGetCurrentThreadWin32Thread())
    {
        /* yes, we got a thread and its the same that opens the clipboard */
        return TRUE;

    }
    /* will fail if not thread (closed) or not open by me*/
    return FALSE;
}

/* IntClipboardFreeWindow it's called when a window was destroyed */
VOID FASTCALL
IntClipboardFreeWindow(PWINDOW_OBJECT window)
{
    /* called from co_UserFreeWindow in window.c */
    /* check if clipboard is not locked by this window, if yes, unlock it */
    if (ClipboardThread == PsGetCurrentThreadWin32Thread())
    {
        /* the window that opens the clipboard was destroyed */
        ClipboardThread = NULL;
        ClipboardWindow = NULL;
        //TODO: free clipboard
    }
    if (window == ClipboardOwnerWindow)
    {
        /* the owner window was destroyed */
        ClipboardOwnerWindow = NULL;
        ClipboardOwnerThread = NULL;
    }
    /* remove window from window chain */
    if (IntIsWindowInChain(window))
    {
		PCLIPBOARDCHAINELEMENT w = IntRemoveWindowFromChain(window);
		if (w)
		{
            ExFreePool(w);
		}
    }
}

BOOL STDCALL
NtUserOpenClipboard(HWND hWnd, DWORD Unknown1)
{

    PWINDOW_OBJECT Window;
    BOOL ret = FALSE;

    UserEnterExclusive();

    sendDrawClipboardMsg = FALSE;
    recentlySetClipboard = FALSE;

    if (ClipboardThread)
    {
        /* clipboard is already open */
        if (ClipboardThread == PsGetCurrentThreadWin32Thread())
        {
            if  (ClipboardOwnerWindow)
            {
                if (ClipboardOwnerWindow->hSelf == hWnd)
                {
                    ret = TRUE;
                }
            }
            else
            {
                 if (hWnd == NULL)
                 {
                    ret = TRUE;
                 }
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -