- Free allocated memory in case GlobalLock fails.
- Implement bitmap copy of graphics screen buffers. It seems that the call to StretchDIBits doesn't work correctly (it copies the image but removes a band of height == Console->Selection.srSelection.Top at the bottom of the copied image), so in the meantime I call SetDIBitsToDevice which does correctly the job. It would be nice that some win32k guy has a look at this... :D
Have fun!

svn path=/trunk/; revision=62513
This commit is contained in:
Hermès Bélusca-Maïto 2014-03-16 02:15:53 +00:00
parent 90989af0c7
commit 2b427f2fba
3 changed files with 113 additions and 16 deletions

View file

@ -16,19 +16,100 @@
/* FUNCTIONS ******************************************************************/
VOID
GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer)
GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData)
{
/*
* This function supposes that the system clipboard was opened.
*/
// PCONSOLE Console = Buffer->Header.Console;
PCONSOLE Console = Buffer->Header.Console;
UNIMPLEMENTED;
HDC hMemDC;
HBITMAP hBitmapTarget, hBitmapOld;
HPALETTE hPalette, hPaletteOld;
ULONG selWidth, selHeight;
if (Buffer->BitMap == NULL) return;
selWidth = Console->Selection.srSelection.Right - Console->Selection.srSelection.Left + 1;
selHeight = Console->Selection.srSelection.Bottom - Console->Selection.srSelection.Top + 1;
DPRINT1("Selection is (%d|%d) to (%d|%d)\n",
Console->Selection.srSelection.Left,
Console->Selection.srSelection.Top,
Console->Selection.srSelection.Right,
Console->Selection.srSelection.Bottom);
hMemDC = CreateCompatibleDC(GuiData->hMemDC);
if (hMemDC == NULL) return;
/* Allocate a bitmap to be given to the clipboard, so it will not be freed here */
hBitmapTarget = CreateCompatibleBitmap(GuiData->hMemDC, selWidth, selHeight);
if (hBitmapTarget == NULL)
{
DeleteDC(hMemDC);
return;
}
/* Select the new bitmap */
hBitmapOld = SelectObject(hMemDC, hBitmapTarget);
/* Change the palette in hMemDC if the current palette does exist */
if (Buffer->PaletteHandle == NULL)
hPalette = GuiData->hSysPalette;
else
hPalette = Buffer->PaletteHandle;
if (hPalette) hPaletteOld = SelectPalette(hMemDC, hPalette, FALSE);
/* Grab the mutex */
NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL);
// The equivalent of a SetDIBitsToDevice call...
// It seems to be broken: it does not copy the tail of the bitmap.
// http://wiki.allegro.cc/index.php?title=StretchDIBits
#if 0
StretchDIBits(hMemDC,
0, 0,
selWidth, selHeight,
Console->Selection.srSelection.Left,
Console->Selection.srSelection.Top,
selWidth, selHeight,
Buffer->BitMap,
Buffer->BitMapInfo,
Buffer->BitMapUsage,
SRCCOPY);
#else
SetDIBitsToDevice(hMemDC,
/* Coordinates / size of the repainted rectangle, in the framebuffer's frame */
0, 0,
selWidth, selHeight,
/* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */
Console->Selection.srSelection.Left,
Console->Selection.srSelection.Top,
0,
Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight
Buffer->BitMap,
Buffer->BitMapInfo,
Buffer->BitMapUsage);
#endif
/* Release the mutex */
NtReleaseMutant(Buffer->Mutex, NULL);
/* Restore the palette and the old bitmap */
if (hPalette) SelectPalette(hMemDC, hPaletteOld, FALSE);
SelectObject(hMemDC, hBitmapOld);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmapTarget);
DeleteDC(hMemDC);
}
VOID
GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer)
GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData)
{
/*
* This function supposes that the system clipboard was opened.

View file

@ -1333,8 +1333,12 @@ Quit:
return 0;
}
VOID GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer);
VOID GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer);
VOID
GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData);
VOID
GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData);
static VOID
GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
@ -1346,11 +1350,11 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
if (GetType(Buffer) == TEXTMODE_BUFFER)
{
GuiCopyFromTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer);
GuiCopyFromTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer, GuiData);
}
else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
{
GuiCopyFromGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer);
GuiCopyFromGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer, GuiData);
}
CloseClipboard();
@ -1361,8 +1365,12 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
}
}
VOID GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer);
VOID GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer);
VOID
GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData);
VOID
GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData);
static VOID
GuiConsolePaste(PGUI_CONSOLE_DATA GuiData)
@ -1373,11 +1381,11 @@ GuiConsolePaste(PGUI_CONSOLE_DATA GuiData)
if (GetType(Buffer) == TEXTMODE_BUFFER)
{
GuiPasteToTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer);
GuiPasteToTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer, GuiData);
}
else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
{
GuiPasteToGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer);
GuiPasteToGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer, GuiData);
}
CloseClipboard();
@ -1909,6 +1917,8 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
EnableMenuItem(hMenu, ID_SYSTEM_EDIT_COPY , MF_BYCOMMAND |
((Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) &&
(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) ? MF_ENABLED : MF_GRAYED));
// FIXME: Following whether the active screen buffer is text-mode
// or graphics-mode, search for CF_UNICODETEXT or CF_BITMAP formats.
EnableMenuItem(hMenu, ID_SYSTEM_EDIT_PASTE, MF_BYCOMMAND |
(!(Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) &&
IsClipboardFormatAvailable(CF_UNICODETEXT) ? MF_ENABLED : MF_GRAYED));

View file

@ -30,7 +30,8 @@ COLORREF RGBFromAttrib2(PCONSOLE Console, WORD Attribute)
}
VOID
GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData)
{
/*
* This function supposes that the system clipboard was opened.
@ -72,12 +73,16 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
size += 1; /* Null-termination */
size *= sizeof(WCHAR);
/* Allocate memory, it will be passed to the system and may not be freed here */
/* Allocate some memory area to be given to the clipboard, so it will not be freed here */
hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
if (hData == NULL) return;
data = GlobalLock(hData);
if (data == NULL) return;
if (data == NULL)
{
GlobalFree(hData);
return;
}
DPRINT("Copying %dx%d selection\n", selWidth, selHeight);
dstPos = data;
@ -121,7 +126,8 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
}
VOID
GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData)
{
/*
* This function supposes that the system clipboard was opened.