fb8d73cdc1fe8102ffab168e0026959b84e18091
[reactos.git] / reactos / drivers / setup / blue / font.c
1 /*
2 * PROJECT: ReactOS Setup Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/setup/blue/font.c
5 * PURPOSE: Loading specific fonts into VGA
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7 * Colin Finck (mail@colinfinck.de)
8 * Christoph von Wittich (christoph_vw@reactos.org)
9 */
10
11 /* INCLUDES ***************************************************************/
12
13 #include <ntddk.h>
14 #include "blue.h"
15
16 #define NDEBUG
17 #include <debug.h>
18
19 VOID OpenBitPlane();
20 VOID CloseBitPlane();
21 VOID LoadFont(PUCHAR Bitplane, PUCHAR FontBitfield);
22
23 /* FUNCTIONS ****************************************************************/
24
25 VOID
26 ScrLoadFontTable(UINT32 CodePage)
27 {
28 PHYSICAL_ADDRESS BaseAddress;
29 PUCHAR Bitplane;
30 PUCHAR FontBitfield = NULL;
31 NTSTATUS Status = STATUS_SUCCESS;
32
33 FontBitfield = (PUCHAR) ExAllocatePoolWithTag(NonPagedPool, 2048, TAG_BLUE);
34 if(FontBitfield)
35 {
36 /* open bit plane for font table access */
37 OpenBitPlane();
38
39 /* get pointer to video memory */
40 BaseAddress.QuadPart = BITPLANE_BASE;
41 Bitplane = (PUCHAR)MmMapIoSpace (BaseAddress, 0xFFFF, MmNonCached);
42
43 Status = ExtractFont(CodePage, FontBitfield);
44 if (NT_SUCCESS(Status))
45 LoadFont(Bitplane, FontBitfield);
46
47 MmUnmapIoSpace(Bitplane, 0xFFFF);
48 ExFreePool(FontBitfield);
49
50 /* close bit plane */
51 CloseBitPlane();
52 }
53 }
54
55 /* PRIVATE FUNCTIONS *********************************************************/
56
57 NTSTATUS ExtractFont(UINT32 CodePage, PUCHAR FontBitField)
58 {
59 BOOLEAN bFoundFile = FALSE;
60 HANDLE Handle;
61 NTSTATUS Status;
62 CHAR FileName[20];
63 IO_STATUS_BLOCK IoStatusBlock;
64 OBJECT_ATTRIBUTES ObjectAttributes;
65 UNICODE_STRING LinkName;
66 UNICODE_STRING SourceName;
67 CFHEADER CabFileHeader;
68 CFFILE CabFile;
69 ULONG CabFileOffset = 0;
70 LARGE_INTEGER ByteOffset;
71 WCHAR SourceBuffer[MAX_PATH] = {L'\0'};
72 ULONG ReadCP;
73
74 if(KeGetCurrentIrql() != PASSIVE_LEVEL)
75 return STATUS_INVALID_DEVICE_STATE;
76
77 RtlInitUnicodeString(&LinkName,
78 L"\\SystemRoot");
79
80 InitializeObjectAttributes(&ObjectAttributes,
81 &LinkName,
82 OBJ_CASE_INSENSITIVE,
83 NULL,
84 NULL);
85
86 Status = ZwOpenSymbolicLinkObject(&Handle,
87 SYMBOLIC_LINK_ALL_ACCESS,
88 &ObjectAttributes);
89
90 if (!NT_SUCCESS(Status))
91 return(Status);
92
93 SourceName.Length = 0;
94 SourceName.MaximumLength = MAX_PATH * sizeof(WCHAR);
95 SourceName.Buffer = SourceBuffer;
96
97 Status = ZwQuerySymbolicLinkObject(Handle,
98 &SourceName,
99 NULL);
100 ZwClose(Handle);
101
102 Status = RtlAppendUnicodeToString(&SourceName, L"\\vgafonts.cab");
103 InitializeObjectAttributes(&ObjectAttributes, &SourceName,
104 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
105 NULL, NULL);
106
107 Status = ZwCreateFile(&Handle,
108 GENERIC_READ,
109 &ObjectAttributes, &IoStatusBlock, NULL,
110 FILE_ATTRIBUTE_NORMAL,
111 0,
112 FILE_OPEN,
113 FILE_SYNCHRONOUS_IO_NONALERT,
114 NULL, 0);
115
116 ByteOffset.LowPart = ByteOffset.HighPart = 0;
117
118 if(NT_SUCCESS(Status))
119 {
120 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock,
121 &CabFileHeader, sizeof(CabFileHeader), &ByteOffset, NULL);
122
123 if(NT_SUCCESS(Status))
124 {
125 if(CabFileHeader.Signature == CAB_SIGNATURE)
126 {
127 // We have a valid CAB file!
128 // Read the file table now and decrement the file count on every file. When it's zero, we read the complete table.
129 ByteOffset.LowPart = CabFileHeader.FileTableOffset;
130
131 while(CabFileHeader.FileCount)
132 {
133 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock,
134 &CabFile, sizeof(CabFile), &ByteOffset, NULL);
135
136 if(NT_SUCCESS(Status))
137 {
138 ByteOffset.LowPart += sizeof(CabFile);
139
140 // We assume here that the file name is max. 19 characters (+ 1 NULL character) long.
141 // This should be enough for our purpose.
142 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock,
143 FileName, sizeof(FileName), &ByteOffset, NULL);
144
145 if(NT_SUCCESS(Status))
146 {
147 if(!bFoundFile)
148 {
149 Status = RtlCharToInteger(FileName, 0, &ReadCP);
150 if (NT_SUCCESS(Status) && ReadCP == CodePage)
151 {
152 // We got the correct file.
153 // Save the offset and loop through the rest of the file table to find the position, where the actual data starts.
154 CabFileOffset = CabFile.FileOffset;
155 bFoundFile = TRUE;
156 }
157 }
158
159 ByteOffset.LowPart += strlen(FileName) + 1;
160 }
161 }
162
163 CabFileHeader.FileCount--;
164 }
165
166 // 8 = Size of a CFFOLDER structure (see cabman). As we don't need the values of that structure, just increase the offset here.
167 ByteOffset.LowPart += 8;
168 ByteOffset.LowPart += CabFileOffset;
169
170 // ByteOffset now contains the offset of the actual data, so we can read the RAW font
171 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock,
172 FontBitField, 2048, &ByteOffset, NULL);
173 ZwClose(Handle);
174 return STATUS_SUCCESS;
175 }
176 else
177 {
178 DPRINT1("Error: CAB signature is missing!\n");
179 Status = STATUS_UNSUCCESSFUL;
180 }
181 }
182 else
183 DPRINT1("Error: Cannot read from file\n");
184
185 ZwClose(Handle);
186 return Status;
187 }
188 else
189 {
190 DPRINT1("Error: Cannot open vgafonts.cab\n");
191 return Status;
192 }
193 }
194
195 /* Font-load specific funcs */
196 VOID
197 OpenBitPlane()
198 {
199 /* disable interrupts */
200 _disable();
201
202 /* sequence reg */
203 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_RESET); WRITE_PORT_UCHAR (SEQ_DATA, 0x01);
204 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_ENABLE_WRT_PLANE); WRITE_PORT_UCHAR (SEQ_DATA, 0x04);
205 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_MEM_MODE); WRITE_PORT_UCHAR (SEQ_DATA, 0x07);
206 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_RESET); WRITE_PORT_UCHAR (SEQ_DATA, 0x03);
207
208 /* graphic reg */
209 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_READ_PLANE); WRITE_PORT_UCHAR (GCT_DATA, 0x02);
210 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_RW_MODES); WRITE_PORT_UCHAR (GCT_DATA, 0x00);
211 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_GRAPH_MODE); WRITE_PORT_UCHAR (GCT_DATA, 0x00);
212
213 /* enable interrupts */
214 _enable();
215 }
216
217 VOID
218 CloseBitPlane()
219 {
220 /* disable interrupts */
221 _disable();
222
223 /* sequence reg */
224 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_RESET); WRITE_PORT_UCHAR (SEQ_DATA, 0x01);
225 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_ENABLE_WRT_PLANE); WRITE_PORT_UCHAR (SEQ_DATA, 0x03);
226 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_MEM_MODE); WRITE_PORT_UCHAR (SEQ_DATA, 0x03);
227 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_RESET); WRITE_PORT_UCHAR (SEQ_DATA, 0x03);
228
229 /* graphic reg */
230 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_READ_PLANE); WRITE_PORT_UCHAR (GCT_DATA, 0x00);
231 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_RW_MODES); WRITE_PORT_UCHAR (GCT_DATA, 0x10);
232 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_GRAPH_MODE); WRITE_PORT_UCHAR (GCT_DATA, 0x0e);
233
234 /* enable interrupts */
235 _enable();
236 }
237
238 VOID
239 LoadFont(PUCHAR Bitplane, PUCHAR FontBitfield)
240 {
241 UINT32 i,j;
242
243 for (i=0; i<256; i++)
244 {
245 for (j=0; j<8; j++)
246 {
247 *Bitplane = FontBitfield[i*8+j];
248 Bitplane++;
249 }
250
251 // padding
252 for (j=8; j<32; j++)
253 {
254 *Bitplane = 0;
255 Bitplane++;
256 }
257 }
258 }
259