Sync with trunk r63430.
[reactos.git] / win32ss / user / winsrv / consrv / frontends / gui / graphics.c
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 DPRINT1("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 // PCONSOLE 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 PCONSOLE Console = Buffer->Header.Console;
130 // ASSERT(Console == GuiData->Console);
131
132 if (Buffer->BitMap == NULL) return;
133
134 if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
135
136 rcFramebuffer->left = Buffer->ViewOrigin.X * 1 + rcView->left;
137 rcFramebuffer->top = Buffer->ViewOrigin.Y * 1 + rcView->top;
138 rcFramebuffer->right = Buffer->ViewOrigin.X * 1 + rcView->right;
139 rcFramebuffer->bottom = Buffer->ViewOrigin.Y * 1 + rcView->bottom;
140
141 /* Grab the mutex */
142 NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL);
143
144 /*
145 * The seventh parameter (YSrc) of SetDIBitsToDevice always designates
146 * the Y-coordinate of the "lower-left corner" of the image, be the DIB
147 * in bottom-up or top-down mode.
148 */
149 SetDIBitsToDevice(GuiData->hMemDC,
150 /* Coordinates / size of the repainted rectangle, in the framebuffer's frame */
151 rcFramebuffer->left,
152 rcFramebuffer->top,
153 rcFramebuffer->right - rcFramebuffer->left,
154 rcFramebuffer->bottom - rcFramebuffer->top,
155 /* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */
156 rcFramebuffer->left,
157 rcFramebuffer->top,
158 0,
159 Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight
160 Buffer->BitMap,
161 Buffer->BitMapInfo,
162 Buffer->BitMapUsage);
163
164 /* Release the mutex */
165 NtReleaseMutant(Buffer->Mutex, NULL);
166
167 LeaveCriticalSection(&Console->Lock);
168 }
169
170 /* EOF */