1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Console Server DLL 4 * FILE: win32ss/user/winsrv/consrv/frontends/gui/graphics.c 5 * PURPOSE: GUI Terminal Front-End - Support for graphics-mode screen-buffers 6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include <consrv.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 #include "guiterm.h" 17 18 /* FUNCTIONS ******************************************************************/ 19 20 VOID 21 GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, 22 PGUI_CONSOLE_DATA GuiData) 23 { 24 /* 25 * This function supposes that the system clipboard was opened. 26 */ 27 28 HDC hMemDC; 29 HBITMAP hBitmapTarget, hBitmapOld; 30 HPALETTE hPalette, hPaletteOld; 31 ULONG selWidth, selHeight; 32 33 if (Buffer->BitMap == NULL) return; 34 35 selWidth = GuiData->Selection.srSelection.Right - GuiData->Selection.srSelection.Left + 1; 36 selHeight = GuiData->Selection.srSelection.Bottom - GuiData->Selection.srSelection.Top + 1; 37 DPRINT("Selection is (%d|%d) to (%d|%d)\n", 38 GuiData->Selection.srSelection.Left, 39 GuiData->Selection.srSelection.Top, 40 GuiData->Selection.srSelection.Right, 41 GuiData->Selection.srSelection.Bottom); 42 43 hMemDC = CreateCompatibleDC(GuiData->hMemDC); 44 if (hMemDC == NULL) return; 45 46 /* Allocate a bitmap to be given to the clipboard, so it will not be freed here */ 47 hBitmapTarget = CreateCompatibleBitmap(GuiData->hMemDC, selWidth, selHeight); 48 if (hBitmapTarget == NULL) 49 { 50 DeleteDC(hMemDC); 51 return; 52 } 53 54 /* Select the new bitmap */ 55 hBitmapOld = SelectObject(hMemDC, hBitmapTarget); 56 57 /* Change the palette in hMemDC if the current palette does exist */ 58 if (Buffer->PaletteHandle == NULL) 59 hPalette = GuiData->hSysPalette; 60 else 61 hPalette = Buffer->PaletteHandle; 62 63 if (hPalette) hPaletteOld = SelectPalette(hMemDC, hPalette, FALSE); 64 65 /* Grab the mutex */ 66 NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL); 67 68 // The equivalent of a SetDIBitsToDevice call... 69 // It seems to be broken: it does not copy the tail of the bitmap. 70 // http://wiki.allegro.cc/index.php?title=StretchDIBits 71 #if 0 72 StretchDIBits(hMemDC, 73 0, 0, 74 selWidth, selHeight, 75 GuiData->Selection.srSelection.Left, 76 GuiData->Selection.srSelection.Top, 77 selWidth, selHeight, 78 Buffer->BitMap, 79 Buffer->BitMapInfo, 80 Buffer->BitMapUsage, 81 SRCCOPY); 82 #else 83 SetDIBitsToDevice(hMemDC, 84 /* Coordinates / size of the repainted rectangle, in the framebuffer's frame */ 85 0, 0, 86 selWidth, selHeight, 87 /* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */ 88 GuiData->Selection.srSelection.Left, 89 GuiData->Selection.srSelection.Top, 90 0, 91 Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight 92 Buffer->BitMap, 93 Buffer->BitMapInfo, 94 Buffer->BitMapUsage); 95 #endif 96 97 /* Release the mutex */ 98 NtReleaseMutant(Buffer->Mutex, NULL); 99 100 /* Restore the palette and the old bitmap */ 101 if (hPalette) SelectPalette(hMemDC, hPaletteOld, FALSE); 102 SelectObject(hMemDC, hBitmapOld); 103 104 EmptyClipboard(); 105 SetClipboardData(CF_BITMAP, hBitmapTarget); 106 107 DeleteDC(hMemDC); 108 } 109 110 VOID 111 GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, 112 PGUI_CONSOLE_DATA GuiData) 113 { 114 /* 115 * This function supposes that the system clipboard was opened. 116 */ 117 118 // PCONSRV_CONSOLE Console = Buffer->Header.Console; 119 120 UNIMPLEMENTED; 121 } 122 123 VOID 124 GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, 125 PGUI_CONSOLE_DATA GuiData, 126 PRECT rcView, 127 PRECT rcFramebuffer) 128 { 129 PCONSRV_CONSOLE Console = Buffer->Header.Console; 130 // ASSERT(Console == GuiData->Console); 131 132 SetRectEmpty(rcFramebuffer); 133 134 if (Buffer->BitMap == NULL) return; 135 136 if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return; 137 138 rcFramebuffer->left = Buffer->ViewOrigin.X * 1 + rcView->left; 139 rcFramebuffer->top = Buffer->ViewOrigin.Y * 1 + rcView->top; 140 rcFramebuffer->right = Buffer->ViewOrigin.X * 1 + rcView->right; 141 rcFramebuffer->bottom = Buffer->ViewOrigin.Y * 1 + rcView->bottom; 142 143 /* Grab the mutex */ 144 NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL); 145 146 /* 147 * The seventh parameter (YSrc) of SetDIBitsToDevice always designates 148 * the Y-coordinate of the "lower-left corner" of the image, be the DIB 149 * in bottom-up or top-down mode. 150 */ 151 SetDIBitsToDevice(GuiData->hMemDC, 152 /* Coordinates / size of the repainted rectangle, in the framebuffer's frame */ 153 rcFramebuffer->left, 154 rcFramebuffer->top, 155 rcFramebuffer->right - rcFramebuffer->left, 156 rcFramebuffer->bottom - rcFramebuffer->top, 157 /* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */ 158 rcFramebuffer->left, 159 rcFramebuffer->top, 160 0, 161 Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight 162 Buffer->BitMap, 163 Buffer->BitMapInfo, 164 Buffer->BitMapUsage); 165 166 /* Release the mutex */ 167 NtReleaseMutant(Buffer->Mutex, NULL); 168 169 LeaveCriticalSection(&Console->Lock); 170 } 171 172 /* EOF */ 173