[USER32_WSPRINTF]
[reactos.git] / reactos / drivers / video / displays / vga / objects / offscreen.c
1 /*
2 * PROJECT: ReactOS VGA display driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/video/displays/vga/objects/offscreen.c
5 * PURPOSE: Manages off-screen video memory
6 * PROGRAMMERS: Copyright (C) 1998-2001 ReactOS Team
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <vgaddi.h>
12
13 /* GLOBALS *******************************************************************/
14
15 static LIST_ENTRY SavedBitsList;
16
17 /* FUNCTIONS *****************************************************************/
18
19 VOID
20 VGADDI_BltFromSavedScreenBits(
21 IN ULONG DestX,
22 IN ULONG DestY,
23 IN PSAVED_SCREEN_BITS Src,
24 IN ULONG SizeX,
25 IN ULONG SizeY)
26 {
27 PUCHAR DestOffset;
28 PUCHAR SrcOffset;
29 ULONG i, j;
30
31 /* Select write mode 1. */
32 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
33 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 1);
34
35 SrcOffset = (PUCHAR)vidmem + Src->Offset;
36 for (i = 0; i < SizeY; i++)
37 {
38 DestOffset = (PUCHAR)vidmem + (i + DestY) * 80 + (DestX >> 3);
39 //FIXME: in the loop below we should treat the case when SizeX is not divisible by 8, i.e. partial bytes
40 for (j = 0; j < SizeX>>3; j++, SrcOffset++, DestOffset++)
41 {
42 (VOID)READ_REGISTER_UCHAR(SrcOffset);
43 WRITE_REGISTER_UCHAR(DestOffset, 0);
44 }
45 }
46
47 /* Select write mode 2. */
48 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
49 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2);
50 }
51
52 VOID
53 VGADDI_BltToSavedScreenBits(
54 IN PSAVED_SCREEN_BITS Dest,
55 IN ULONG SourceX,
56 IN ULONG SourceY,
57 IN ULONG SizeX,
58 IN ULONG SizeY)
59 {
60 PUCHAR DestOffset;
61 PUCHAR SrcOffset;
62 ULONG i, j;
63
64 /* Select write mode 1. */
65 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
66 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 1);
67
68 DestOffset = (PUCHAR)vidmem + Dest->Offset;
69
70 for (i = 0; i < SizeY; i++)
71 {
72 SrcOffset = (PUCHAR)vidmem + (SourceY + i) * 80 + (SourceX >> 3);
73 //FIXME: in the loop below we should treat the case when SizeX is not divisible by 8, i.e. partial bytes
74 for (j = 0; j < SizeX>>3; j++, SrcOffset++, DestOffset++)
75 {
76 (VOID)READ_REGISTER_UCHAR(SrcOffset);
77 WRITE_REGISTER_UCHAR(DestOffset, 0);
78 }
79 }
80
81 /* Select write mode 2. */
82 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5);
83 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2);
84 }
85
86 VOID
87 VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits)
88 {
89 SavedBits->Free = TRUE;
90
91 if (SavedBits->ListEntry.Blink != &SavedBitsList)
92 {
93 PSAVED_SCREEN_BITS Previous;
94
95 Previous = CONTAINING_RECORD(SavedBits->ListEntry.Blink,
96 SAVED_SCREEN_BITS, ListEntry);
97 if (Previous->Free)
98 {
99 Previous->Size += SavedBits->Size;
100 RemoveEntryList(&SavedBits->ListEntry);
101 EngFreeMem(SavedBits);
102 SavedBits = Previous;
103 }
104 }
105 if (SavedBits->ListEntry.Flink != &SavedBitsList)
106 {
107 PSAVED_SCREEN_BITS Next;
108
109 Next = CONTAINING_RECORD(SavedBits->ListEntry.Flink, SAVED_SCREEN_BITS,
110 ListEntry);
111 if (Next->Free)
112 {
113 SavedBits->Size += Next->Size;
114 RemoveEntryList(&SavedBits->ListEntry);
115 EngFreeMem(SavedBits);
116 }
117 }
118 }
119
120 PSAVED_SCREEN_BITS
121 VGADDI_AllocSavedScreenBits(ULONG Size)
122 {
123 PSAVED_SCREEN_BITS Current;
124 PLIST_ENTRY CurrentEntry;
125 PSAVED_SCREEN_BITS Best;
126 PSAVED_SCREEN_BITS New;
127
128 Best = NULL;
129 CurrentEntry = SavedBitsList.Flink;
130 while (CurrentEntry != &SavedBitsList)
131 {
132 Current = CONTAINING_RECORD(CurrentEntry, SAVED_SCREEN_BITS, ListEntry);
133
134 if (Current->Free && Current->Size >= Size &&
135 (Best == NULL || (Current->Size - Size) < (Best->Size - Size)))
136 {
137 Best = Current;
138 }
139
140 CurrentEntry = CurrentEntry->Flink;
141 }
142
143 if (!Best)
144 return NULL;
145
146 if (Best->Size == Size)
147 {
148 Best->Free = FALSE;
149 return Best;
150 }
151 else
152 {
153 New = EngAllocMem(0, sizeof(SAVED_SCREEN_BITS), ALLOC_TAG);
154 New->Free = FALSE;
155 New->Offset = Best->Offset + Size;
156 New->Size = Size;
157 Best->Size -= Size;
158 InsertHeadList(&Best->ListEntry, &New->ListEntry);
159 return New;
160 }
161 }
162
163 VOID
164 VGADDI_InitializeOffScreenMem(
165 IN ULONG Start,
166 IN ULONG Length)
167 {
168 PSAVED_SCREEN_BITS FreeBits;
169
170 InitializeListHead(&SavedBitsList);
171
172 FreeBits = EngAllocMem(0, sizeof(SAVED_SCREEN_BITS), ALLOC_TAG);
173 FreeBits->Free = TRUE;
174 FreeBits->Offset = Start;
175 FreeBits->Size = Length;
176 InsertHeadList(&SavedBitsList, &FreeBits->ListEntry);
177 }