Sync with trunk r62754.
[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 PCONSOLE Console = Buffer->Header.Console;
29
30 HDC hMemDC;
31 HBITMAP hBitmapTarget, hBitmapOld;
32 HPALETTE hPalette, hPaletteOld;
33 ULONG selWidth, selHeight;
34
35 if (Buffer->BitMap == NULL) return;
36
37 selWidth = Console->Selection.srSelection.Right - Console->Selection.srSelection.Left + 1;
38 selHeight = Console->Selection.srSelection.Bottom - Console->Selection.srSelection.Top + 1;
39 DPRINT1("Selection is (%d|%d) to (%d|%d)\n",
40 Console->Selection.srSelection.Left,
41 Console->Selection.srSelection.Top,
42 Console->Selection.srSelection.Right,
43 Console->Selection.srSelection.Bottom);
44
45 hMemDC = CreateCompatibleDC(GuiData->hMemDC);
46 if (hMemDC == NULL) return;
47
48 /* Allocate a bitmap to be given to the clipboard, so it will not be freed here */
49 hBitmapTarget = CreateCompatibleBitmap(GuiData->hMemDC, selWidth, selHeight);
50 if (hBitmapTarget == NULL)
51 {
52 DeleteDC(hMemDC);
53 return;
54 }
55
56 /* Select the new bitmap */
57 hBitmapOld = SelectObject(hMemDC, hBitmapTarget);
58
59 /* Change the palette in hMemDC if the current palette does exist */
60 if (Buffer->PaletteHandle == NULL)
61 hPalette = GuiData->hSysPalette;
62 else
63 hPalette = Buffer->PaletteHandle;
64
65 if (hPalette) hPaletteOld = SelectPalette(hMemDC, hPalette, FALSE);
66
67 /* Grab the mutex */
68 NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL);
69
70 // The equivalent of a SetDIBitsToDevice call...
71 // It seems to be broken: it does not copy the tail of the bitmap.
72 // http://wiki.allegro.cc/index.php?title=StretchDIBits
73 #if 0
74 StretchDIBits(hMemDC,
75 0, 0,
76 selWidth, selHeight,
77 Console->Selection.srSelection.Left,
78 Console->Selection.srSelection.Top,
79 selWidth, selHeight,
80 Buffer->BitMap,
81 Buffer->BitMapInfo,
82 Buffer->BitMapUsage,
83 SRCCOPY);
84 #else
85 SetDIBitsToDevice(hMemDC,
86 /* Coordinates / size of the repainted rectangle, in the framebuffer's frame */
87 0, 0,
88 selWidth, selHeight,
89 /* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */
90 Console->Selection.srSelection.Left,
91 Console->Selection.srSelection.Top,
92 0,
93 Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight
94 Buffer->BitMap,
95 Buffer->BitMapInfo,
96 Buffer->BitMapUsage);
97 #endif
98
99 /* Release the mutex */
100 NtReleaseMutant(Buffer->Mutex, NULL);
101
102 /* Restore the palette and the old bitmap */
103 if (hPalette) SelectPalette(hMemDC, hPaletteOld, FALSE);
104 SelectObject(hMemDC, hBitmapOld);
105
106 EmptyClipboard();
107 SetClipboardData(CF_BITMAP, hBitmapTarget);
108
109 DeleteDC(hMemDC);
110 }
111
112 VOID
113 GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
114 PGUI_CONSOLE_DATA GuiData)
115 {
116 /*
117 * This function supposes that the system clipboard was opened.
118 */
119
120 // PCONSOLE Console = Buffer->Header.Console;
121
122 UNIMPLEMENTED;
123 }
124
125 VOID
126 GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
127 PGUI_CONSOLE_DATA GuiData,
128 PRECT rcView,
129 PRECT rcFramebuffer)
130 {
131 if (Buffer->BitMap == NULL) return;
132
133 rcFramebuffer->left = Buffer->ViewOrigin.X * 1 + rcView->left;
134 rcFramebuffer->top = Buffer->ViewOrigin.Y * 1 + rcView->top;
135 rcFramebuffer->right = Buffer->ViewOrigin.X * 1 + rcView->right;
136 rcFramebuffer->bottom = Buffer->ViewOrigin.Y * 1 + rcView->bottom;
137
138 /* Grab the mutex */
139 NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL);
140
141 /*
142 * The seventh parameter (YSrc) of SetDIBitsToDevice always designates
143 * the Y-coordinate of the "lower-left corner" of the image, be the DIB
144 * in bottom-up or top-down mode.
145 */
146 SetDIBitsToDevice(GuiData->hMemDC,
147 /* Coordinates / size of the repainted rectangle, in the framebuffer's frame */
148 rcFramebuffer->left,
149 rcFramebuffer->top,
150 rcFramebuffer->right - rcFramebuffer->left,
151 rcFramebuffer->bottom - rcFramebuffer->top,
152 /* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */
153 rcFramebuffer->left,
154 rcFramebuffer->top,
155 0,
156 Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight
157 Buffer->BitMap,
158 Buffer->BitMapInfo,
159 Buffer->BitMapUsage);
160
161 /* Release the mutex */
162 NtReleaseMutant(Buffer->Mutex, NULL);
163 }
164
165 /* EOF */