- merge audio headers
[reactos.git] / 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
73 if(KeGetCurrentIrql() != PASSIVE_LEVEL)
74 return STATUS_INVALID_DEVICE_STATE;
75
76 RtlInitUnicodeString(&LinkName,
77 L"\\SystemRoot");
78
79 InitializeObjectAttributes(&ObjectAttributes,
80 &LinkName,
81 OBJ_CASE_INSENSITIVE,
82 NULL,
83 NULL);
84
85 Status = ZwOpenSymbolicLinkObject(&Handle,
86 SYMBOLIC_LINK_ALL_ACCESS,
87 &ObjectAttributes);
88
89 if (!NT_SUCCESS(Status))
90 return(Status);
91
92 SourceName.Length = 0;
93 SourceName.MaximumLength = _MAX_PATH * sizeof(WCHAR);
94 SourceName.Buffer = SourceBuffer;
95
96 Status = ZwQuerySymbolicLinkObject(Handle,
97 &SourceName,
98 NULL);
99 ZwClose(Handle);
100
101 Status = RtlAppendUnicodeToString(&SourceName, L"\\vgafonts.cab");
102 InitializeObjectAttributes(&ObjectAttributes, &SourceName,
103 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
104 NULL, NULL);
105
106 Status = ZwCreateFile(&Handle,
107 GENERIC_READ,
108 &ObjectAttributes, &IoStatusBlock, NULL,
109 FILE_ATTRIBUTE_NORMAL,
110 0,
111 FILE_OPEN,
112 FILE_SYNCHRONOUS_IO_NONALERT,
113 NULL, 0);
114
115 ByteOffset.LowPart = ByteOffset.HighPart = 0;
116
117 if(NT_SUCCESS(Status))
118 {
119 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock,
120 &CabFileHeader, sizeof(CabFileHeader), &ByteOffset, NULL);
121
122 if(NT_SUCCESS(Status))
123 {
124 if(CabFileHeader.Signature == CAB_SIGNATURE)
125 {
126 // We have a valid CAB file!
127 // Read the file table now and decrement the file count on every file. When it's zero, we read the complete table.
128 ByteOffset.LowPart = CabFileHeader.FileTableOffset;
129
130 while(CabFileHeader.FileCount)
131 {
132 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock,
133 &CabFile, sizeof(CabFile), &ByteOffset, NULL);
134
135 if(NT_SUCCESS(Status))
136 {
137 ByteOffset.LowPart += sizeof(CabFile);
138
139 // We assume here that the file name is max. 19 characters (+ 1 NULL character) long.
140 // This should be enough for our purpose.
141 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock,
142 FileName, sizeof(FileName), &ByteOffset, NULL);
143
144 if(NT_SUCCESS(Status))
145 {
146 if(!bFoundFile && (UINT32)atoi(FileName) == CodePage)
147 {
148 // We got the correct file.
149 // Save the offset and loop through the rest of the file table to find the position, where the actual data starts.
150 CabFileOffset = CabFile.FileOffset;
151 bFoundFile = TRUE;
152 }
153
154 ByteOffset.LowPart += strlen(FileName) + 1;
155 }
156 }
157
158 CabFileHeader.FileCount--;
159 }
160
161 // 8 = Size of a CFFOLDER structure (see cabman). As we don't need the values of that structure, just increase the offset here.
162 ByteOffset.LowPart += 8;
163 ByteOffset.LowPart += CabFileOffset;
164
165 // ByteOffset now contains the offset of the actual data, so we can read the RAW font
166 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock,
167 FontBitField, 2048, &ByteOffset, NULL);
168 ZwClose(Handle);
169 return STATUS_SUCCESS;
170 }
171 else
172 {
173 DPRINT1("Error: CAB signature is missing!\n");
174 Status = STATUS_UNSUCCESSFUL;
175 }
176 }
177 else
178 DPRINT1("Error: Cannot read from file\n");
179
180 ZwClose(Handle);
181 return Status;
182 }
183 else
184 {
185 DPRINT1("Error: Cannot open vgafonts.cab\n");
186 return Status;
187 }
188 }
189
190 /* Font-load specific funcs */
191 VOID
192 OpenBitPlane()
193 {
194 /* disable interrupts */
195 _disable();
196
197 /* sequence reg */
198 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_RESET); WRITE_PORT_UCHAR (SEQ_DATA, 0x01);
199 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_ENABLE_WRT_PLANE); WRITE_PORT_UCHAR (SEQ_DATA, 0x04);
200 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_MEM_MODE); WRITE_PORT_UCHAR (SEQ_DATA, 0x07);
201 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_RESET); WRITE_PORT_UCHAR (SEQ_DATA, 0x03);
202
203 /* graphic reg */
204 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_READ_PLANE); WRITE_PORT_UCHAR (GCT_DATA, 0x02);
205 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_RW_MODES); WRITE_PORT_UCHAR (GCT_DATA, 0x00);
206 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_GRAPH_MODE); WRITE_PORT_UCHAR (GCT_DATA, 0x00);
207
208 /* enable interrupts */
209 _enable();
210 }
211
212 VOID
213 CloseBitPlane()
214 {
215 /* disable interrupts */
216 _disable();
217
218 /* sequence reg */
219 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_RESET); WRITE_PORT_UCHAR (SEQ_DATA, 0x01);
220 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_ENABLE_WRT_PLANE); WRITE_PORT_UCHAR (SEQ_DATA, 0x03);
221 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_MEM_MODE); WRITE_PORT_UCHAR (SEQ_DATA, 0x03);
222 WRITE_PORT_UCHAR (SEQ_COMMAND, SEQ_RESET); WRITE_PORT_UCHAR (SEQ_DATA, 0x03);
223
224 /* graphic reg */
225 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_READ_PLANE); WRITE_PORT_UCHAR (GCT_DATA, 0x00);
226 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_RW_MODES); WRITE_PORT_UCHAR (GCT_DATA, 0x10);
227 WRITE_PORT_UCHAR (GCT_COMMAND, GCT_GRAPH_MODE); WRITE_PORT_UCHAR (GCT_DATA, 0x0e);
228
229 /* enable interrupts */
230 _enable();
231 }
232
233 VOID
234 LoadFont(PUCHAR Bitplane, PUCHAR FontBitfield)
235 {
236 UINT32 i,j;
237
238 for (i=0; i<256; i++)
239 {
240 for (j=0; j<8; j++)
241 {
242 *Bitplane = FontBitfield[i*8+j];
243 Bitplane++;
244 }
245
246 // padding
247 for (j=8; j<32; j++)
248 {
249 *Bitplane = 0;
250 Bitplane++;
251 }
252 }
253 }
254