|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: enable.c
3: *
4: * This module contains the functions that enable and disable the
5: * driver, the pdev, and the surface.
6: *
7: * Copyright (c) 1992 Microsoft Corporation
8: \**************************************************************************/
9:
10: #include "driver.h"
11:
12: //
13: // Build the driver function table gadrvfn with function index/address pairs
14: //
15:
16: DRVFN gadrvfn[] = {
17: { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV },
18: { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV },
19: { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV },
20: { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface },
21: { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface },
22: { INDEX_DrvAssertMode, (PFN) DrvAssertMode },
23: { INDEX_DrvGetModes, (PFN) DrvGetModes },
24: { INDEX_DrvDitherColor, (PFN) DrvDitherColor },
25: { INDEX_DrvSetPalette, (PFN) DrvSetPalette },
26: { INDEX_DrvCopyBits, (PFN) DrvCopyBits },
27: { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape },
28: { INDEX_DrvBitBlt, (PFN) DrvBitBlt },
29: { INDEX_DrvTextOut, (PFN) DrvTextOut },
30: { INDEX_DrvStrokePath, (PFN) DrvStrokePath },
31: { INDEX_DrvFillPath, (PFN) DrvFillPath },
32: { INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush },
33: { INDEX_DrvStretchBlt, (PFN) DrvStretchBlt },
34: { INDEX_DrvPaint, (PFN) DrvPaint }
35: };
36:
37: /******************************Public*Routine******************************\
38: * DrvEnableDriver
39: *
40: * Enables the driver by retrieving the drivers function table and version.
41: *
42: \**************************************************************************/
43:
44: BOOL DrvEnableDriver(
45: ULONG iEngineVersion,
46: ULONG cj,
47: PDRVENABLEDATA pded)
48: {
49: UNREFERENCED_PARAMETER(iEngineVersion);
50:
51: // Engine Version is passed down so future drivers can support previous
52: // engine versions. A next generation driver can support both the old
53: // and new engine conventions if told what version of engine it is
54: // working with. For the first version the driver does nothing with it.
55:
56: // Fill in as much as we can.
57:
58: if (cj >= sizeof(DRVENABLEDATA))
59: pded->pdrvfn = gadrvfn;
60:
61: if (cj >= (sizeof(ULONG) * 2))
62: pded->c = sizeof(gadrvfn) / sizeof(DRVFN);
63:
64: // DDI version this driver was targeted for is passed back to engine.
65: // Future graphic's engine may break calls down to old driver format.
66:
67: if (cj >= sizeof(ULONG))
68: pded->iDriverVersion = DDI_DRIVER_VERSION;
69:
70: return(TRUE);
71: }
72:
73: /******************************Public*Routine******************************\
74: * DrvDisableDriver
75: *
76: * Tells the driver it is being disabled. Release any resources allocated in
77: * DrvEnableDriver.
78: *
79: \**************************************************************************/
80:
81: VOID DrvDisableDriver(VOID)
82: {
83: return;
84: }
85:
86: /******************************Public*Routine******************************\
87: * DrvEnablePDEV
88: *
89: * DDI function, Enables the Physical Device.
90: *
91: * Return Value: device handle to pdev.
92: *
93: \**************************************************************************/
94:
95: DHPDEV DrvEnablePDEV(
96: DEVMODEW *pDevmode, // Pointer to DEVMODE
97: PWSTR pwszLogAddress, // Logical address
98: ULONG cPatterns, // number of patterns
99: HSURF *ahsurfPatterns, // return standard patterns
100: ULONG cjGdiInfo, // Length of memory pointed to by pGdiInfo
101: ULONG *pGdiInfo, // Pointer to GdiInfo structure
102: ULONG cjDevInfo, // Length of following PDEVINFO structure
103: DEVINFO *pDevInfo, // physical device information structure
104: PWSTR pwszDataFile, // DataFile - not used
105: PWSTR pwszDeviceName, // DeviceName - not used
106: HANDLE hDriver) // Handle to base driver
107: {
108: GDIINFO GdiInfo;
109: DEVINFO DevInfo;
110: PPDEV ppdev;
111: BYTE *pjTemp;
112: INT i;
113:
114: UNREFERENCED_PARAMETER(pwszLogAddress);
115: UNREFERENCED_PARAMETER(pwszDataFile);
116: UNREFERENCED_PARAMETER(pwszDeviceName);
117:
118: // Allocate a physical device structure.
119:
120: ppdev = (PPDEV) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(PDEV));
121:
122: if (ppdev == (PPDEV) NULL)
123: {
124: RIP("Couldn't allocate PDEV buffer");
125: goto error0;
126: }
127:
128: // Create the table used for flipping bits 0-3 and 4-7 when drawing text.
129: // This table must be aligned to a 256-byte boundary.
130: ppdev->pjGlyphFlipTableBase =
131: (BYTE *) LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT),
132: ((256+256)*sizeof(UCHAR)));
133: if (ppdev->pjGlyphFlipTableBase == NULL) {
134: goto error01;
135: }
136:
137: // Round the table start up to the nearest 256 byte boundary, because the
138: // table must start on 256-byte boundaries for look-up reasons
139:
140: ppdev->pjGlyphFlipTable =
141: (BYTE *) ((ULONG) (ppdev->pjGlyphFlipTableBase + 0xFF) & ~0xFF);
142:
143: // Set the table to convert bits 76543210 to 45670123, which we need for
144: // drawing text in planar mode (because plane 0 is the leftmost, not
145: // rightmost, pixel)
146:
147: pjTemp = ppdev->pjGlyphFlipTable;
148: for (i=0; i<256; i++) {
149: *pjTemp++ = ((i & 0x80) >> 3) |
150: ((i & 0x40) >> 1) |
151: ((i & 0x20) << 1) |
152: ((i & 0x10) << 3) |
153: ((i & 0x08) >> 3) |
154: ((i & 0x04) >> 1) |
155: ((i & 0x02) << 1) |
156: ((i & 0x01) << 3);
157: }
158:
159: // Set up pointers in PDEV to temporary structures we build up to return.
160:
161: ppdev->pGdiInfo = &GdiInfo;
162: ppdev->pDevInfo = &DevInfo;
163:
164: // Save the screen handle in the PDEV.
165:
166: ppdev->hDriver = hDriver;
167:
168: // Get the current screen mode information. Set up device caps and devinfo.
169:
170: if (!bInitPDEV(ppdev,pDevmode))
171: {
172: DISPDBG((0,"vga256 Couldn't initialize PDEV"));
173: goto error1;
174: }
175:
176: // Initialize palette information.
177:
178: if (!bInitPaletteInfo(ppdev))
179: {
180: RIP("Couldn't initialize palette");
181: goto error1;
182: }
183:
184: // Initialize device standard patterns.
185:
186: if (!bInitPatterns(ppdev, min(cPatterns, HS_DDI_MAX)))
187: {
188: RIP("Couldn't initialize patterns");
189: goto error2;
190: }
191:
192: // Copy the devinfo into the engine buffer.
193:
194: memcpy(pDevInfo, ppdev->pDevInfo, min(sizeof(DEVINFO), cjDevInfo));
195:
196: // Set the ahsurfPatterns array to handles each of the standard
197: // patterns that were just created.
198:
199: memcpy((PVOID) ahsurfPatterns, ppdev->ahbmPat, ppdev->cPatterns*sizeof(HBITMAP));
200:
201: // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this
202: // pdev.
203:
204: memcpy(pGdiInfo, ppdev->pGdiInfo, min(cjGdiInfo, sizeof(GDIINFO)));
205:
206: // Set NULL into pointers for stack allocated memory.
207:
208: ppdev->pGdiInfo = (GDIINFO *) NULL;
209: ppdev->pDevInfo = (DEVINFO *) NULL;
210:
211: // Create a clip object we can use when we're given a NULL clip object:
212:
213: ppdev->pcoNull = EngCreateClip();
214: if (ppdev->pcoNull == NULL)
215: {
216: RIP("Couldn't create clip");
217: goto error2;
218: }
219:
220: ppdev->pdda = EngCreateDDA();
221: if (ppdev->pdda == NULL)
222: {
223: RIP("Couldn't create DDA object");
224: goto error3;
225: }
226:
227: ppdev->pcoNull->iDComplexity = DC_RECT;
228: ppdev->pcoNull->rclBounds.left = 0;
229: ppdev->pcoNull->rclBounds.top = 0;
230: ppdev->pcoNull->rclBounds.right = ppdev->cxScreen;
231: ppdev->pcoNull->rclBounds.bottom = ppdev->cyScreen;
232: ppdev->pcoNull->fjOptions = OC_BANK_CLIP;
233:
234: // pvSaveScan0 is non-NULL only when enumerating banks:
235:
236: ppdev->pvSaveScan0 = NULL;
237:
238: // We're all done:
239:
240: return((DHPDEV) ppdev);
241:
242: error3:
243: EngDeleteDDA(ppdev->pdda);
244:
245: error2:
246: vDisablePatterns(ppdev);
247: vDisablePalette(ppdev);
248:
249: error1:
250: LocalFree(ppdev->pjGlyphFlipTable);
251:
252: error01:
253: LocalFree(ppdev);
254:
255: error0:
256: return((DHPDEV) 0);
257: }
258:
259: /******************************Public*Routine******************************\
260: * DrvCompletePDEV
261: *
262: * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
263: *
264: \**************************************************************************/
265:
266: VOID DrvCompletePDEV(
267: DHPDEV dhpdev,
268: HDEV hdev)
269: {
270: ((PPDEV) dhpdev)->hdevEng = hdev;
271: }
272:
273: /******************************Public*Routine******************************\
274: * DrvDisablePDEV
275: *
276: * Release the resources allocated in DrvEnablePDEV. If a surface has been
277: * enabled DrvDisableSurface will have already been called.
278: *
279: \**************************************************************************/
280:
281: VOID DrvDisablePDEV(
282: DHPDEV dhpdev)
283: {
284: PPDEV ppdev = (PPDEV) dhpdev;
285:
286: EngUnlockSurface(ppdev->psoTmp);
287: EngDeleteSurface((HSURF) ppdev->hbmTmp);
288: LocalFree(ppdev->pvTmp);
289: EngDeleteClip(ppdev->pcoNull);
290: EngDeleteDDA(ppdev->pdda);
291: vDisablePalette(ppdev);
292: vDisablePatterns(ppdev);
293: LocalFree(ppdev->pjGlyphFlipTable);
294: LocalFree(dhpdev);
295: }
296:
297: /******************************Public*Routine******************************\
298: * DrvEnableSurface
299: *
300: * Enable the surface for the device. Hook the calls this driver supports.
301: *
302: * Return: Handle to the surface if successful, 0 for failure.
303: *
304: \**************************************************************************/
305:
306: HSURF DrvEnableSurface(
307: DHPDEV dhpdev)
308: {
309: PPDEV ppdev;
310: HSURF hsurf;
311: HSURF hsurfBm;
312: SIZEL sizl;
313: ULONG ulBitmapType;
314: FLONG flHooks;
315:
316: // Create engine bitmap around frame buffer.
317:
318: ppdev = (PPDEV) dhpdev;
319:
320: if (!bInitSURF(ppdev, TRUE))
321: goto error0;
322:
323: if (!bInit256ColorPalette(ppdev))
324: goto error0;
325:
326: sizl.cx = ppdev->cxScreen;
327: sizl.cy = ppdev->cyScreen;
328:
329: ulBitmapType = BMF_8BPP;
330: flHooks = HOOKS_BMF8BPP;
331:
332: ASSERTVGA(ppdev->ulBitCount == 8, "Can only handle 8bpp VGAs");
333:
334: hsurfBm = (HSURF) EngCreateBitmap(sizl,
335: (ULONG) ppdev->lDeltaScreen,
336: (ULONG) (ulBitmapType),
337: (FLONG) (((ppdev->lDeltaScreen > 0)
338: ? BMF_TOPDOWN
339: : 0)),
340: (PVOID) (ppdev->pjScreen));
341: if (hsurfBm == 0)
342: {
343: RIP("Couldn't create surface");
344: goto error0;
345: }
346:
347: if (!EngAssociateSurface(hsurfBm, ppdev->hdevEng, 0))
348: {
349: RIP("Couldn't create or associate surface");
350: goto error1;
351: }
352:
353: ppdev->hsurfBm = hsurfBm;
354:
355: ppdev->pSurfObj = EngLockSurface(hsurfBm);
356: if (ppdev->pSurfObj == NULL)
357: {
358: RIP("Couldn't lock surface");
359: goto error1;
360: }
361:
362: hsurf = EngCreateSurface((DHSURF) ppdev, sizl);
363: if (hsurf == 0)
364: {
365: RIP("Couldn't create surface");
366: goto error2;
367: }
368:
369: if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks))
370: {
371: RIP("Couldn't associate surface");
372: goto error3;
373: }
374:
375: ppdev->hsurfEng = hsurf;
376:
377: // Disable all the clipping.
378:
379: if (!bEnableBanking(ppdev))
380: {
381: RIP("Couldn't initialize banking");
382: goto error3;
383: }
384:
385: ppdev->pvTmp = (PVOID) LocalAlloc(LMEM_FIXED, TMP_BUFFER_SIZE);
386: if (ppdev->pvTmp == NULL)
387: {
388: RIP("Couldn't allocate temporary buffer");
389: goto error4;
390: }
391:
392: ASSERTVGA(ppdev->lNextScan != 0, "lNextScan shouldn't be zero");
393:
394: sizl.cx = ppdev->lNextScan;
395: sizl.cy = TMP_BUFFER_SIZE / abs(ppdev->lNextScan);
396:
397: ppdev->hbmTmp = EngCreateBitmap(sizl, sizl.cx, BMF_8BPP, 0, ppdev->pvTmp);
398: if (ppdev->hbmTmp == (HBITMAP) 0)
399: {
400: RIP("Couldn't create temporary bitmap");
401: goto error5;
402: }
403:
404: ppdev->psoTmp = EngLockSurface((HSURF) ppdev->hbmTmp);
405: if (ppdev->psoTmp == (SURFOBJ*) NULL)
406: {
407: RIP("Couldn't lock temporary surface");
408: goto error6;
409: }
410:
411: // Attempt to initialize the brush cache; if this fails, it sets a flag in
412: // the PDEV instructing us to punt brush fills to the engine
413: vInitBrushCache(ppdev);
414:
415: return(hsurf);
416:
417: error6:
418: EngDeleteSurface((HSURF) ppdev->hbmTmp);
419:
420: error5:
421: LocalFree(ppdev->pvTmp);
422:
423: error4:
424: vDisableBanking(ppdev);
425:
426: error3:
427: EngDeleteSurface(hsurf);
428:
429: error2:
430: EngUnlockSurface(ppdev->pSurfObj);
431:
432: error1:
433: EngDeleteSurface(hsurfBm);
434:
435: error0:
436: return((HSURF) 0);
437: }
438:
439: /******************************Public*Routine******************************\
440: * DrvDisableSurface
441: *
442: * Free resources allocated by DrvEnableSurface. Release the surface.
443: *
444: \**************************************************************************/
445:
446: VOID DrvDisableSurface(
447: DHPDEV dhpdev)
448: {
449: PPDEV ppdev = (PPDEV) dhpdev;
450:
451: EngUnlockSurface(ppdev->psoTmp);
452: EngDeleteSurface((HSURF) ppdev->hbmTmp);
453: LocalFree(ppdev->pvTmp);
454: EngDeleteSurface(ppdev->hsurfEng);
455: vDisableSURF(ppdev);
456: vDisableBrushCache(ppdev);
457: ppdev->hsurfEng = (HSURF) 0;
458: vDisableBanking(ppdev);
459: }
460:
461: /******************************Public*Routine******************************\
462: * DrvAssertMode
463: *
464: * This asks the device to reset itself to the mode of the pdev passed in.
465: *
466: \**************************************************************************/
467:
468: VOID DrvAssertMode(
469: DHPDEV dhpdev,
470: BOOL bEnable)
471: {
472: PPDEV ppdev = (PPDEV) dhpdev;
473: ULONG ulReturn;
474:
475: if (bEnable)
476: {
477: // The screen must be reenabled, reinitialize the device to
478: // a clean state.
479:
480: bInitSURF(ppdev, FALSE);
481:
482: // Restore the off screen data. This protects the Desktop
483: // from a DOS application that might trash the off screen
484: // memory.
485:
486: // Blow away our brush cache because a full-screen app may have
487: // overwritten the video memory where we cache our brushes:
488:
489: vResetBrushCache(ppdev);
490: }
491: else
492: {
493: // Call the kernel driver to reset the device to a known state.
494:
495: if (!DeviceIoControl(ppdev->hDriver,
496: IOCTL_VIDEO_RESET_DEVICE,
497: NULL,
498: 0,
499: NULL,
500: 0,
501: &ulReturn,
502: NULL))
503: {
504: RIP("VIDEO_RESET_DEVICE failed");
505: }
506: }
507:
508: return;
509: }
510:
511: /******************************Public*Routine******************************\
512: * DrvGetModes
513: *
514: * Returns the list of available modes for the device.
515: *
516: \**************************************************************************/
517:
518: ULONG DrvGetModes(
519: HANDLE hDriver,
520: ULONG cjSize,
521: DEVMODEW *pdm)
522:
523: {
524:
525: DWORD cModes;
526: DWORD cbOutputSize;
527: PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
528: DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
529: DWORD cbModeSize;
530:
531: DISPDBG((2, "Vga256.dll: DrvGetModes\n"));
532:
533: cModes = getAvailableModes(hDriver,
534: (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
535: &cbModeSize);
536:
537: if (cModes == 0)
538: {
539: DISPDBG((0, "VGA256 DISP DrvGetModes failed to get mode information"));
540: return 0;
541: }
542:
543: if (pdm == NULL)
544: {
545: cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
546: }
547: else
548: {
549: //
550: // Now copy the information for the supported modes back into the output
551: // buffer
552: //
553:
554: cbOutputSize = 0;
555:
556: pVideoTemp = pVideoModeInformation;
557:
558: do
559: {
560: if (pVideoTemp->Length != 0)
561: {
562: if (cOutputModes == 0)
563: {
564: break;
565: }
566:
567: //
568: // Zero the entire structure to start off with.
569: //
570:
571: memset(pdm, 0, sizeof(DEVMODEW));
572:
573: //
574: // Set the name of the device to the name of the DLL.
575: //
576:
577: memcpy(&(pdm->dmDeviceName), L"vga256", sizeof(L"vga256"));
578:
579: pdm->dmSpecVersion = DM_SPECVERSION;
580: pdm->dmDriverVersion = DM_SPECVERSION;
581:
582: //
583: // We currently do not support Extra information in the driver
584: //
585:
586: pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
587:
588: pdm->dmSize = sizeof(DEVMODEW);
589: pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
590: pVideoTemp->BitsPerPlane;
591: pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
592: pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
593: pdm->dmDisplayFrequency = pVideoTemp->Frequency;
594:
595: if (pVideoTemp->AttributeFlags & VIDEO_MODE_INTERLACED)
596: {
597: pdm->dmDisplayFlags |= DM_INTERLACED;
598: }
599:
600: //
601: // Go to the next DEVMODE entry in the buffer.
602: //
603:
604: cOutputModes--;
605:
606: pdm = (LPDEVMODEW) ( ((ULONG)pdm) + sizeof(DEVMODEW) +
607: DRIVER_EXTRA_SIZE);
608:
609: cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
610:
611: }
612:
613: pVideoTemp = (PVIDEO_MODE_INFORMATION)
614: (((PUCHAR)pVideoTemp) + cbModeSize);
615:
616: } while (--cModes);
617: }
618:
619: LocalFree(pVideoModeInformation);
620:
621: return cbOutputSize;
622:
623: }
624:
625:
626: /******************************Public*Routine******************************\
627: * DrvSetPointerShape
628: *
629: * Sets the new pointer shape.
630: \**************************************************************************/
631:
632: ULONG DrvSetPointerShape
633: (
634: SURFOBJ *pso,
635: SURFOBJ *psoMask,
636: SURFOBJ *psoColor,
637: XLATEOBJ *pxlo,
638: LONG xHot,
639: LONG yHot,
640: LONG x,
641: LONG y,
642: RECTL *prcl,
643: FLONG fl
644: )
645: {
646: return(SPS_DECLINE);
647: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.