VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/enable.c@ 4124

Last change on this file since 4124 was 4124, checked in by vboxsync, 17 years ago

new surface code (disabled by default)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 40.6 KB
Line 
1/******************************Module*Header*******************************\
2*
3* *******************
4* * GDI SAMPLE CODE *
5* *******************
6*
7* Module Name: enable.c
8*
9* This module contains the functions that enable and disable the
10* driver, the pdev, and the surface.
11*
12* Copyright (c) 1992-1998 Microsoft Corporation
13\**************************************************************************/
14
15#include "driver.h"
16#include "dd.h"
17#include <VBoxDisplay.h>
18
19// The driver function table with all function index/address pairs
20
21// Hook functions to track dirty rectangles and generate RDP orders.
22// NT4 functions
23DRVFN gadrvfn_nt4[] = {
24 { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV }, // 0
25 { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV }, // 1
26 { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV }, // 2
27 { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface }, // 3
28 { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface }, // 4
29 { INDEX_DrvAssertMode, (PFN) DrvAssertMode }, // 5
30 { INDEX_DrvOffset, (PFN) DrvOffset }, // 6
31 { INDEX_DrvDisableDriver, (PFN) DrvDisableDriver }, // 8
32 { INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush }, // 12
33 { INDEX_DrvDitherColor, (PFN) DrvDitherColor }, // 13
34 { INDEX_DrvStrokePath, (PFN) DrvStrokePath }, // 14
35 { INDEX_DrvFillPath, (PFN) DrvFillPath }, // 15
36 { INDEX_DrvPaint, (PFN) DrvPaint }, // 17
37 { INDEX_DrvBitBlt, (PFN) DrvBitBlt }, // 18
38 { INDEX_DrvCopyBits, (PFN) DrvCopyBits }, // 19
39 { INDEX_DrvStretchBlt, (PFN) DrvStretchBlt, }, // 20
40 { INDEX_DrvSetPalette, (PFN) DrvSetPalette }, // 22
41 { INDEX_DrvTextOut, (PFN) DrvTextOut }, // 23
42 { INDEX_DrvEscape, (PFN) DrvEscape }, // 24
43 { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape }, // 29
44 { INDEX_DrvMovePointer, (PFN) DrvMovePointer }, // 30
45 { INDEX_DrvLineTo, (PFN) DrvLineTo }, // 31
46 { INDEX_DrvSynchronize, (PFN) DrvSynchronize }, // 38
47 { INDEX_DrvSaveScreenBits, (PFN) DrvSaveScreenBits }, // 40
48 { INDEX_DrvGetModes, (PFN) DrvGetModes }, // 41
49#ifdef VBOX_WITH_DDRAW
50 { INDEX_DrvGetDirectDrawInfo, (PFN) DrvGetDirectDrawInfo }, // 59 0x3b
51 { INDEX_DrvEnableDirectDraw, (PFN) DrvEnableDirectDraw }, // 60 0x3c
52 { INDEX_DrvDisableDirectDraw, (PFN) DrvDisableDirectDraw }, // 61 0x3d
53#endif
54};
55/* Experimental begin */
56BOOL APIENTRY DrvResetPDEV(
57 DHPDEV dhpdevOld,
58 DHPDEV dhpdevNew
59 )
60{
61 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, dhpdevOld, dhpdevNew));
62 return TRUE;
63}
64
65BOOL DrvNineGrid (PVOID x1, PVOID x2, PVOID x3, PVOID x4, PVOID x5, PVOID x6, PVOID x7, PVOID x8, PVOID x9)
66{
67 DISPDBG((0, "Experimental %s: %p, %p, %p, %p, %p, %p, %p, %p, %p\n", __FUNCTION__, x1, x2, x3, x4, x5, x6, x7, x8, x9));
68 return FALSE;
69}
70
71VOID APIENTRY DrvDestroyFont(
72 FONTOBJ *pfo)
73{
74 DISPDBG((0, "Experimental %s: %p\n", __FUNCTION__, pfo));
75}
76
77ULONG APIENTRY DrvEscape(SURFOBJ *pso, ULONG iEsc, ULONG cjIn, PVOID pvIn, ULONG cjOut, PVOID pvOut)
78{
79 PDEV* ppdev = (PDEV*) pso->dhpdev;
80
81 DISPDBG((0, "%s: %p, %p, %p, %p, %p, %p\n", __FUNCTION__, pso, iEsc, cjIn, pvIn, cjOut, pvOut));
82
83 switch(iEsc)
84 {
85#ifdef VBOX_WITH_OPENGL
86 case OPENGL_GETINFO:
87 {
88 if ( cjOut >= sizeof(OPENGL_INFO)
89 && pvOut)
90 {
91 POPENGL_INFO pInfo = (POPENGL_INFO)pvOut;
92
93 pInfo->dwVersion = 2;
94 pInfo->dwDriverVersion = 1;
95 pInfo->szDriverName[0] = 'V';
96 pInfo->szDriverName[1] = 'B';
97 pInfo->szDriverName[2] = 'o';
98 pInfo->szDriverName[3] = 'x';
99 pInfo->szDriverName[4] = 'O';
100 pInfo->szDriverName[5] = 'G';
101 pInfo->szDriverName[6] = 'L';
102 pInfo->szDriverName[7] = 0;
103
104 DISPDBG((0, "OPENGL_GETINFO\n"));
105 return cjOut;
106 }
107 else
108 DISPDBG((0, "OPENGL_GETINFO invalid size %d\n", cjOut)); /* It doesn't matter that we fail here. Opengl32 will fall back to software rendering when this escape is not supported. */
109 break;
110 }
111#endif
112
113 case VBOXESC_SETVISIBLEREGION:
114 {
115 LPRGNDATA lpRgnData = (LPRGNDATA)pvIn;
116
117 DISPDBG((0, "VBOXESC_SETVISIBLEREGION\n"));
118
119 if ( cjIn >= sizeof(RGNDATAHEADER)
120 && pvIn
121 && lpRgnData->rdh.dwSize == sizeof(RGNDATAHEADER)
122 && lpRgnData->rdh.iType == RDH_RECTANGLES
123 && cjIn == lpRgnData->rdh.nCount * sizeof(RECT) + sizeof(RGNDATAHEADER))
124 {
125 DWORD ulReturn, i;
126 PRTRECT pRTRect;
127 RECT *pRect = (RECT *)&lpRgnData->Buffer;
128
129 pRTRect = (PRTRECT) EngAllocMem(0, lpRgnData->rdh.nCount*sizeof(RTRECT), ALLOC_TAG);
130 for (i=0;i<lpRgnData->rdh.nCount;i++)
131 {
132 DISPDBG((0, "New visible rectangle (%d,%d) (%d,%d)\n", pRect[i].left, pRect[i].bottom, pRect[i].right, pRect[i].top));
133 pRTRect[i].xLeft = pRect[i].left;
134 pRTRect[i].yBottom = pRect[i].bottom;
135 pRTRect[i].xRight = pRect[i].right;
136 pRTRect[i].yTop = pRect[i].top;
137 }
138
139 if (EngDeviceIoControl(ppdev->hDriver,
140 IOCTL_VIDEO_VBOX_SETVISIBLEREGION,
141 pRTRect,
142 lpRgnData->rdh.nCount*sizeof(RTRECT),
143 NULL,
144 0,
145 &ulReturn))
146 {
147 DISPDBG((0, "DISP DrvAssertMode failed IOCTL_VIDEO_VBOX_SETVISIBLEREGION\n"));
148 return 0;
149 }
150 else
151 {
152 DISPDBG((0, "DISP IOCTL_VIDEO_VBOX_SETVISIBLEREGION successful\n"));
153 return 1;
154 }
155
156 }
157 else
158 {
159 if (pvIn)
160 DISPDBG((0, "check failed rdh.dwSize=%x iType=%d size=%d expected size=%d\n", lpRgnData->rdh.dwSize, lpRgnData->rdh.iType, cjIn, lpRgnData->rdh.nCount * sizeof(RECT) + sizeof(RGNDATAHEADER)));
161 }
162
163 break;
164 }
165
166 case QUERYESCSUPPORT:
167 if ( cjIn == sizeof(DWORD)
168 && pvIn)
169 {
170 DWORD nEscapeQuery = *(DWORD *)pvIn;
171
172 switch(nEscapeQuery)
173 {
174#ifdef VBOX_WITH_OPENGL
175 case OPENGL_GETINFO:
176 return 1;
177#endif
178 default:
179 DISPDBG((0, "QUERYESCSUPPORT %d unsupported\n", nEscapeQuery));
180 break;
181 }
182 }
183 else
184 DISPDBG((0, "QUERYESCSUPPORT invalid size %d\n", cjOut));
185 break;
186
187 default:
188 DISPDBG((0, "Unsupported Escape %d\n", iEsc));
189 break;
190 }
191 return 0;
192}
193
194BOOL DrvConnect (PVOID x1, PVOID x2, PVOID x3, PVOID x4)
195{
196 DISPDBG((0, "Experimental %s: %p, %p, %p, %p\n", __FUNCTION__, x1, x2, x3, x4));
197 return TRUE;
198}
199
200BOOL DrvDisconnect (PVOID x1, PVOID x2)
201{
202 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, x1, x2));
203 return FALSE;
204}
205
206BOOL DrvReconnect (PVOID x1, PVOID x2)
207{
208 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, x1, x2));
209 return FALSE;
210}
211
212BOOL DrvShadowConnect (PVOID x1, PVOID x2)
213{
214 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, x1, x2));
215 return FALSE;
216}
217
218BOOL DrvShadowDisconnect (PVOID x1, PVOID x2)
219{
220 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, x1, x2));
221 return FALSE;
222}
223
224
225/* Experimental end */
226
227// W2K,XP functions
228DRVFN gadrvfn_nt5[] = {
229 { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV }, // 0 0x0
230 { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV }, // 1 0x1
231 { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV }, // 2 0x2
232 { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface }, // 3 0x3
233 { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface }, // 4 0x4
234 { INDEX_DrvAssertMode, (PFN) DrvAssertMode }, // 5 0x5
235 { INDEX_DrvDisableDriver, (PFN) DrvDisableDriver }, // 8 0x8
236 { INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush }, // 12 0xc
237 { INDEX_DrvDitherColor, (PFN) DrvDitherColor }, // 13 0xd
238 { INDEX_DrvStrokePath, (PFN) DrvStrokePath }, // 14 0xe
239 { INDEX_DrvFillPath, (PFN) DrvFillPath }, // 15 0xf
240 { INDEX_DrvPaint, (PFN) DrvPaint }, // 17 0x11
241 { INDEX_DrvBitBlt, (PFN) DrvBitBlt }, // 18 0x12
242 { INDEX_DrvCopyBits, (PFN) DrvCopyBits }, // 19 0x13
243 { INDEX_DrvStretchBlt, (PFN) DrvStretchBlt, }, // 20 0x14
244 { INDEX_DrvSetPalette, (PFN) DrvSetPalette }, // 22 0x16
245 { INDEX_DrvTextOut, (PFN) DrvTextOut }, // 23 0x17
246 { INDEX_DrvEscape, (PFN) DrvEscape }, // 24 0x18
247 { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape }, // 29 0x1d
248 { INDEX_DrvMovePointer, (PFN) DrvMovePointer }, // 30 0x1e
249 { INDEX_DrvLineTo, (PFN) DrvLineTo }, // 31 0x1f
250 { INDEX_DrvSynchronize, (PFN) DrvSynchronize }, // 38 0x26
251 { INDEX_DrvSaveScreenBits, (PFN) DrvSaveScreenBits }, // 40 0x28
252 { INDEX_DrvGetModes, (PFN) DrvGetModes }, // 41 0x29
253#ifdef VBOX_WITH_DDRAW
254 { INDEX_DrvGetDirectDrawInfo, (PFN) DrvGetDirectDrawInfo }, // 59 0x3b
255 { INDEX_DrvEnableDirectDraw, (PFN) DrvEnableDirectDraw }, // 60 0x3c
256 { INDEX_DrvDisableDirectDraw, (PFN) DrvDisableDirectDraw }, // 61 0x3d
257 { INDEX_DrvDeriveSurface, (PFN) DrvDeriveSurface }, // 85
258#endif
259 { INDEX_DrvNotify, (PFN) DrvNotify }, // 87 0x57
260// /* Experimental. */
261// { 0x7, (PFN) DrvResetPDEV }, // 0x7
262// { 0x5b, (PFN) DrvNineGrid }, // 0x5b
263// { 0x2b, (PFN) DrvDestroyFont }, // 0x2b
264// { 0x18, (PFN) DrvEscape }, // 0x18
265// { 0x4d, (PFN) DrvConnect }, // 0x4d
266// { 0x4e, (PFN) DrvDisconnect }, // 0x4e
267// { 0x4f, (PFN) DrvReconnect }, // 0x4f
268// { 0x50, (PFN) DrvShadowConnect }, // 0x50
269// { 0x51, (PFN) DrvShadowDisconnect }, // 0x51
270
271};
272
273// Required hook bits will be set up according to DDI version
274static ULONG gflHooks = 0;
275 BOOL g_bOnNT40 = TRUE; /* assume NT4 guest by default */
276
277#define HOOKS_BMF8BPP gflHooks
278#define HOOKS_BMF16BPP gflHooks
279#define HOOKS_BMF24BPP gflHooks
280#define HOOKS_BMF32BPP gflHooks
281
282HSEMAPHORE ghsemHwBuffer = 0;
283
284/******************************Public*Routine******************************\
285* DrvEnableDriver
286*
287* Enables the driver by retrieving the drivers function table and version.
288*
289\**************************************************************************/
290
291BOOL DrvEnableDriver(
292ULONG iEngineVersion,
293ULONG cj,
294PDRVENABLEDATA pded)
295{
296// Engine Version is passed down so future drivers can support previous
297// engine versions. A next generation driver can support both the old
298// and new engine conventions if told what version of engine it is
299// working with. For the first version the driver does nothing with it.
300
301 DISPDBG((0, "VBoxDisp::DrvEnableDriver called. iEngine version = %08X\n", iEngineVersion));
302
303 // Set up hook flags to intercept all functions which can generate VRDP orders
304 gflHooks = HOOK_BITBLT | HOOK_TEXTOUT | HOOK_FILLPATH |
305 HOOK_COPYBITS | HOOK_STROKEPATH | HOOK_LINETO |
306#ifdef VBOX_NEW_SURFACE_CODE
307 HOOK_PAINT | HOOK_STRETCHBLT | HOOK_SYNCHRONIZE;
308#else
309 HOOK_PAINT | HOOK_STRETCHBLT | HOOK_SYNCHRONIZEACCESS;
310#endif
311 // Set up g_bOnNT40 based on the value in iEngineVersion
312 if(iEngineVersion >= DDI_DRIVER_VERSION_NT5)
313 g_bOnNT40 = FALSE;
314
315// Fill in as much as we can.
316
317 if (cj >= sizeof(DRVENABLEDATA))
318 pded->pdrvfn = (iEngineVersion >= DDI_DRIVER_VERSION_NT5)?
319 gadrvfn_nt5:
320 gadrvfn_nt4;
321
322
323 if (cj >= (sizeof(ULONG) * 2))
324 pded->c = (iEngineVersion >= DDI_DRIVER_VERSION_NT5)?
325 sizeof(gadrvfn_nt5) / sizeof(DRVFN):
326 sizeof(gadrvfn_nt4) / sizeof(DRVFN);
327
328// DDI version this driver was targeted for is passed back to engine.
329// Future graphic's engine may break calls down to old driver format.
330
331 if (cj >= sizeof(ULONG))
332 pded->iDriverVersion = (iEngineVersion >= DDI_DRIVER_VERSION_NT5)?
333 DDI_DRIVER_VERSION_NT5:
334 DDI_DRIVER_VERSION_NT4;
335
336 if (!ghsemHwBuffer)
337 {
338 ghsemHwBuffer = EngCreateSemaphore ();
339 }
340
341 return(TRUE);
342}
343
344/******************************Public*Routine******************************\
345* DrvDisableDriver
346*
347* Tells the driver it is being disabled. Release any resources allocated in
348* DrvEnableDriver.
349*
350\**************************************************************************/
351
352VOID DrvDisableDriver(VOID)
353{
354 DISPDBG((0, "VBoxDisp::DrvDisableDriver called.\n"));
355
356 if (ghsemHwBuffer)
357 {
358 EngDeleteSemaphore (ghsemHwBuffer);
359 ghsemHwBuffer = NULL;
360 }
361
362 return;
363}
364
365/******************************Public*Routine******************************\
366* DrvEnablePDEV
367*
368* DDI function, Enables the Physical Device.
369*
370* Return Value: device handle to pdev.
371*
372\**************************************************************************/
373
374DHPDEV DrvEnablePDEV(
375DEVMODEW *pDevmode, // Pointer to DEVMODE
376PWSTR pwszLogAddress, // Logical address
377ULONG cPatterns, // number of patterns
378HSURF *ahsurfPatterns, // return standard patterns
379ULONG cjGdiInfo, // Length of memory pointed to by pGdiInfo
380ULONG *pGdiInfo, // Pointer to GdiInfo structure
381ULONG cjDevInfo, // Length of following PDEVINFO structure
382DEVINFO *pDevInfo, // physical device information structure
383HDEV hdev, // HDEV, used for callbacks
384PWSTR pwszDeviceName, // DeviceName - not used
385HANDLE hDriver) // Handle to base driver
386{
387 GDIINFO GdiInfo;
388 DEVINFO DevInfo;
389 PPDEV ppdev = (PPDEV) NULL;
390
391 DISPDBG((0, "VBoxDisp::DrvEnablePDEV called\n"));
392
393 UNREFERENCED_PARAMETER(pwszLogAddress);
394 UNREFERENCED_PARAMETER(pwszDeviceName);
395
396 RtlZeroMemory(&DevInfo, sizeof (DEVINFO));
397 RtlZeroMemory(&GdiInfo, sizeof (GDIINFO));
398
399 // Allocate a physical device structure.
400
401 ppdev = (PPDEV) EngAllocMem(0, sizeof(PDEV), ALLOC_TAG);
402
403 if (ppdev == (PPDEV) NULL)
404 {
405 DISPDBG((0, "DISP DrvEnablePDEV failed EngAllocMem\n"));
406 return((DHPDEV) 0);
407 }
408
409 memset(ppdev, 0, sizeof(PDEV));
410
411 // Save the screen handle in the PDEV.
412
413 ppdev->hDriver = hDriver;
414
415 // Get the current screen mode information. Set up device caps and devinfo.
416
417 if (!bInitPDEV(ppdev, pDevmode, &GdiInfo, &DevInfo))
418 {
419 DISPDBG((0,"DISP DrvEnablePDEV failed\n"));
420 goto error_free;
421 }
422
423 // Initialize the cursor information.
424
425 if (!bInitPointer(ppdev, &DevInfo))
426 {
427 // Not a fatal error...
428 DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
429 }
430
431 // Initialize palette information.
432
433 if (!bInitPaletteInfo(ppdev, &DevInfo))
434 {
435 DISPDBG((0, "DrvEnablePDEV failed bInitPalette\n"));
436 goto error_free;
437 }
438
439// // Start a thread that will process notifications from VMMDev
440// if (!bInitNotificationThread(ppdev))
441// {
442// DISPDBG((0, "DrvEnablePDEV failed bInitNotificationThread\n"));
443// goto error_free;
444// }
445
446 // Copy the devinfo into the engine buffer.
447
448 DISPDBG((0, "VBoxDisp::DrvEnablePDEV: sizeof(DEVINFO) = %d, cjDevInfo = %d, alpha = %d\n", sizeof(DEVINFO), cjDevInfo, DevInfo.flGraphicsCaps2 & GCAPS2_ALPHACURSOR));
449
450// @todo seems to be not necessary. these bits are initialized in screen.c DevInfo.flGraphicsCaps |= GCAPS_OPAQUERECT |
451// GCAPS_DITHERONREALIZE |
452// GCAPS_PALMANAGED |
453// GCAPS_ALTERNATEFILL |
454// GCAPS_WINDINGFILL |
455// GCAPS_MONO_DITHER |
456// GCAPS_COLOR_DITHER |
457// GCAPS_ASYNCMOVE;
458//
459// DevInfo.flGraphicsCaps |= GCAPS_DITHERONREALIZE;
460
461 DevInfo.flGraphicsCaps2 |= GCAPS2_RESERVED1; /* @todo figure out what is this. */
462
463 memcpy(pDevInfo, &DevInfo, min(sizeof(DEVINFO), cjDevInfo));
464
465 // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this
466 // pdev.
467
468 memcpy(pGdiInfo, &GdiInfo, min(cjGdiInfo, sizeof(GDIINFO)));
469
470 DISPDBG((0, "VBoxDisp::DrvEnablePDEV completed\n"));
471
472 return((DHPDEV) ppdev);
473
474 // Error case for failure.
475error_free:
476 EngFreeMem(ppdev);
477 return((DHPDEV) 0);
478}
479
480/******************************Public*Routine******************************\
481* DrvCompletePDEV
482*
483* Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
484*
485\**************************************************************************/
486
487VOID DrvCompletePDEV(
488DHPDEV dhpdev,
489HDEV hdev)
490{
491 DISPDBG((0, "VBoxDisp::DrvCompletePDEV called\n"));
492 ((PPDEV) dhpdev)->hdevEng = hdev;
493}
494
495/******************************Public*Routine******************************\
496* DrvDisablePDEV
497*
498* Release the resources allocated in DrvEnablePDEV. If a surface has been
499* enabled DrvDisableSurface will have already been called.
500*
501\**************************************************************************/
502
503VOID DrvDisablePDEV(
504DHPDEV dhpdev)
505{
506 DISPDBG((0, "VBoxDisp::DrvDisablePDEV called\n"));
507// vStopNotificationThread ((PPDEV) dhpdev);
508 vDisablePalette((PPDEV) dhpdev);
509
510 /* Free the driver's VBVA resources. */
511 vboxVbvaDisable ((PPDEV) dhpdev);
512
513 EngFreeMem(dhpdev);
514}
515
516/******************************Public*Routine******************************\
517* VOID DrvOffset
518*
519* DescriptionText
520*
521\**************************************************************************/
522
523BOOL DrvOffset(
524SURFOBJ* pso,
525LONG x,
526LONG y,
527FLONG flReserved)
528{
529 PDEV* ppdev = (PDEV*) pso->dhpdev;
530
531 // Add back last offset that we subtracted. I could combine the next
532 // two statements, but I thought this was more clear. It's not
533 // performance critical anyway.
534
535 ppdev->pjScreen += ((ppdev->ptlOrg.y * ppdev->lDeltaScreen) +
536 (ppdev->ptlOrg.x * ((ppdev->ulBitCount+1) >> 3)));
537
538 // Subtract out new offset
539
540 ppdev->pjScreen -= ((y * ppdev->lDeltaScreen) +
541 (x * ((ppdev->ulBitCount+1) >> 3)));
542
543 ppdev->ptlOrg.x = x;
544 ppdev->ptlOrg.y = y;
545
546 return(TRUE);
547}
548
549/******************************Public*Routine******************************\
550* DrvEnableSurface
551*
552* Enable the surface for the device. Hook the calls this driver supports.
553*
554* Return: Handle to the surface if successful, 0 for failure.
555*
556\**************************************************************************/
557
558HSURF DrvEnableSurface(DHPDEV dhpdev)
559{
560 PPDEV ppdev;
561 HSURF hsurf;
562 SIZEL sizl;
563 ULONG ulBitmapType;
564 FLONG flHooks;
565#ifdef VBOX_NEW_SURFACE_CODE
566 PVBOXSURF psurf;
567#endif
568 DISPDBG((0, "DISP DrvEnableSurface called\n"));
569
570 // Create engine bitmap around frame buffer.
571
572 ppdev = (PPDEV) dhpdev;
573
574 ppdev->ptlOrg.x = 0;
575 ppdev->ptlOrg.y = 0;
576
577 if (!bInitSURF(ppdev, TRUE))
578 {
579 DISPDBG((0, "DISP DrvEnableSurface failed bInitSURF\n"));
580 return(FALSE);
581 }
582
583 DISPDBG((0, "DISP DrvEnableSurface bInitSURF success\n"));
584
585 sizl.cx = ppdev->cxScreen;
586 sizl.cy = ppdev->cyScreen;
587
588 if (ppdev->ulBitCount == 8)
589 {
590 if (!bInit256ColorPalette(ppdev)) {
591 DISPDBG((0, "DISP DrvEnableSurface failed to init the 8bpp palette\n"));
592 return(FALSE);
593 }
594 ulBitmapType = BMF_8BPP;
595 flHooks = HOOKS_BMF8BPP;
596 }
597 else if (ppdev->ulBitCount == 16)
598 {
599 ulBitmapType = BMF_16BPP;
600 flHooks = HOOKS_BMF16BPP;
601 }
602 else if (ppdev->ulBitCount == 24)
603 {
604 ulBitmapType = BMF_24BPP;
605 flHooks = HOOKS_BMF24BPP;
606 }
607 else
608 {
609 ulBitmapType = BMF_32BPP;
610 flHooks = HOOKS_BMF32BPP;
611 }
612
613#ifdef VBOX_NEW_SURFACE_CODE
614 psurf = (PVBOXSURF)EngAllocMem(0, sizeof(VBOXSURF), ALLOC_TAG);
615 if (psurf == NULL)
616 {
617 DISPDBG((0, "DrvEnableSurface: failed pdsurf memory allocation\n"));
618 goto l_Failure;
619 }
620 ppdev->pdsurfScreen = psurf;
621 psurf->ppdev = ppdev;
622
623 //
624 // On NT4.0 we create a GDI managed bitmap as the primay surface. But
625 // on NT5.0 we create a device managed primary.
626 //
627 // On NT4.0 we still use our driver's accleration capabilities by
628 // doing a trick with EngLockSurface on the GDI managed primary.
629 //
630
631 if(g_bOnNT40)
632 {
633 hsurf = (HSURF) EngCreateBitmap(sizl,
634 ppdev->lDeltaScreen,
635 ulBitmapType,
636 (ppdev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0,
637 (PVOID)(ppdev->pjScreen));
638 }
639 else
640 {
641 hsurf = (HSURF)EngCreateDeviceSurface((DHSURF)psurf, sizl,
642 ulBitmapType);
643 }
644
645 if ( hsurf == 0 )
646 {
647 DISPDBG((0, "DrvEnableSurface: failed EngCreateDeviceBitmap\n"));
648 goto l_Failure;
649 }
650
651 //
652 // On NT5.0 we call EngModifSurface to expose our device surface to
653 // GDI. We cant do this on NT4.0 hence we call EngAssociateSurface.
654 //
655
656 if(g_bOnNT40)
657 {
658 //
659 // We have to associate the surface we just created with our physical
660 // device so that GDI can get information related to the PDEV when
661 // it's drawing to the surface (such as, for example, the length of
662 // styles on the device when simulating styled lines).
663 //
664
665 //
666 // On NT4.0 we dont want to be called to Synchronize Access
667 //
668 LONG myflHooks = flHooks;
669 myflHooks &= ~HOOK_SYNCHRONIZE;
670
671 if (!EngAssociateSurface(hsurf, ppdev->hdevEng, myflHooks))
672 {
673 DISPDBG((0, "DrvEnableSurface: failed EngAssociateSurface\n"));
674 goto l_Failure;
675 }
676
677 //
678 // Jam in the value of dhsurf into screen SURFOBJ. We do this to
679 // make sure the driver acclerates Drv calls we hook and not
680 // punt them back to GDI as the SURFOBJ's dhsurf = 0.
681 //
682 ppdev->psoScreenBitmap = EngLockSurface(hsurf);
683 if(ppdev->psoScreenBitmap == 0)
684 {
685 DISPDBG((0, "DrvEnableSurface: failed EngLockSurface\n"));
686 goto l_Failure;
687 }
688
689 ppdev->psoScreenBitmap->dhsurf = (DHSURF)hsurf;
690
691 }
692 else
693 {
694 //
695 // Tell GDI about the screen surface. This will enable GDI to render
696 // directly to the screen.
697 //
698
699 if ( !EngModifySurface(hsurf,
700 ppdev->hdevEng,
701 flHooks,
702 MS_NOTSYSTEMMEMORY,
703 (DHSURF)psurf,
704 ppdev->pjScreen,
705 ppdev->lDeltaScreen,
706 NULL))
707 {
708 DISPDBG((0, "DrvEnableSurface: failed EngModifySurface"));
709 goto l_Failure;
710 }
711 }
712 ppdev->hsurfScreen = hsurf;
713 ppdev->flHooks = flHooks;
714 ppdev->ulBitmapType = ulBitmapType;
715#else
716 hsurf = (HSURF) EngCreateBitmap(sizl,
717 ppdev->lDeltaScreen,
718 ulBitmapType,
719 (ppdev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0,
720 (PVOID) (ppdev->pjScreen));
721
722 if (hsurf == (HSURF) 0)
723 {
724 DISPDBG((0, "DISP DrvEnableSurface failed EngCreateBitmap\n"));
725 goto l_Failure;
726 }
727 else
728 {
729 ppdev->hsurfScreenBitmap = hsurf;
730
731 if (!EngAssociateSurface(hsurf, ppdev->hdevEng, 0))
732 {
733 DISPDBG((0, "DISP DrvEnableSurface failed EngAssociateSurface for ScreenBitmap.\n"));
734 goto l_Failure;
735 }
736 else
737 {
738 SURFOBJ *pso = EngLockSurface(hsurf);
739
740 ppdev->psoScreenBitmap = pso;
741
742 hsurf = (HSURF) EngCreateDeviceSurface((DHSURF)pso,
743 sizl,
744 ulBitmapType);
745
746 if (hsurf == (HSURF) 0)
747 {
748 DISPDBG((0, "DISP DrvEnableSurface failed EngCreateDeviceSurface\n"));
749 goto l_Failure;
750 }
751 else
752 {
753 ppdev->hsurfScreen = hsurf;
754 /* Must set dhsurf to make sure GDI doesn't ignore our hooks */
755 ppdev->psoScreenBitmap->dhsurf = (DHSURF)hsurf;
756
757 if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks))
758 {
759 DISPDBG((0, "DISP DrvEnableSurface failed EngAssociateSurface for Screen.\n"));
760 goto l_Failure;
761 }
762 else
763 {
764 ppdev->flHooks = flHooks;
765 ppdev->ulBitmapType = ulBitmapType;
766 }
767 }
768 }
769 }
770#endif /* VBOX_NEW_SURFACE_CODE */
771 return ppdev->hsurfScreen;
772
773l_Failure:
774
775 DrvDisableSurface(dhpdev);
776
777 return((HSURF)0);
778}
779
780/******************************Public*Routine******************************\
781* DrvDisableSurface
782*
783* Free resources allocated by DrvEnableSurface. Release the surface.
784*
785\**************************************************************************/
786
787VOID DrvDisableSurface(
788DHPDEV dhpdev)
789{
790 PPDEV ppdev = (PPDEV)dhpdev;
791
792 DISPDBG((0, "VBoxDisp::DrvDisableSurface called\n"));
793 if (ppdev->psoScreenBitmap)
794 {
795 EngUnlockSurface (ppdev->psoScreenBitmap);
796 ppdev->psoScreenBitmap = NULL;
797 }
798
799 if (ppdev->hsurfScreen)
800 {
801 EngDeleteSurface(ppdev->hsurfScreen);
802 ppdev->hsurfScreen = (HSURF)0;
803 }
804#ifdef VBOX_NEW_SURFACE_CODE
805 if (ppdev->pdsurfScreen)
806 {
807 EngFreeMem(ppdev->pdsurfScreen);
808 ppdev->pdsurfScreen = NULL;
809 }
810#else
811 if (ppdev->hsurfScreenBitmap)
812 {
813 EngDeleteSurface(ppdev->hsurfScreenBitmap);
814 ppdev->hsurfScreenBitmap = (HSURF)0;
815 }
816#endif
817 vDisableSURF(ppdev);
818}
819
820/******************************Public*Routine******************************\
821* DrvAssertMode
822*
823* This asks the device to reset itself to the mode of the pdev passed in.
824*
825\**************************************************************************/
826
827BOOL DrvAssertMode(
828DHPDEV dhpdev,
829BOOL bEnable)
830{
831 PPDEV ppdev = (PPDEV) dhpdev;
832 ULONG ulReturn;
833 PBYTE pjScreen;
834
835 DISPDBG((0, "DISP DrvAssertMode called bEnable = %d\n", bEnable));
836
837 if (bEnable)
838 {
839 pjScreen = ppdev->pjScreen;
840
841 if (!bInitSURF(ppdev, FALSE))
842 {
843 DISPDBG((0, "DISP DrvAssertMode failed bInitSURF\n"));
844 return (FALSE);
845 }
846
847#ifdef VBOX_NEW_SURFACE_CODE
848 todo
849#endif
850 if (pjScreen != ppdev->pjScreen)
851 {
852 HSURF hsurf;
853 SIZEL sizl;
854 SURFOBJ *pso;
855
856 DISPDBG((0, "DISP DrvAssertMode Screen pointer has changed!!!\n"));
857
858 sizl.cx = ppdev->cxScreen;
859 sizl.cy = ppdev->cyScreen;
860
861 hsurf = (HSURF) EngCreateBitmap(sizl,
862 ppdev->lDeltaScreen,
863 ppdev->ulBitmapType,
864 (ppdev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0,
865 (PVOID) (ppdev->pjScreen));
866
867 if (hsurf == (HSURF) 0)
868 {
869 DISPDBG((0, "DISP DrvAssertMode failed EngCreateBitmap\n"));
870 return FALSE;
871 }
872
873 pso = EngLockSurface(hsurf);
874
875 if (ppdev->psoScreenBitmap)
876 {
877 EngUnlockSurface (ppdev->psoScreenBitmap);
878 ppdev->psoScreenBitmap = NULL;
879 }
880
881 if (ppdev->hsurfScreenBitmap)
882 {
883 EngDeleteSurface(ppdev->hsurfScreenBitmap);
884 ppdev->hsurfScreenBitmap = (HSURF)0;
885 }
886
887 ppdev->hsurfScreenBitmap = hsurf;
888 ppdev->psoScreenBitmap = pso;
889 }
890
891 if (!EngAssociateSurface(ppdev->hsurfScreenBitmap, ppdev->hdevEng, 0))
892 {
893 DISPDBG((0, "DISP DrvAssertMode failed EngAssociateSurface for ScreenBitmap.\n"));
894 return FALSE;
895 }
896
897 if (!EngAssociateSurface(ppdev->hsurfScreen, ppdev->hdevEng, ppdev->flHooks))
898 {
899 DISPDBG((0, "DISP DrvAssertMode failed EngAssociateSurface for Screen.\n"));
900 return FALSE;
901 }
902
903 return TRUE;
904 }
905 else
906 {
907 //
908 // We must give up the display.
909 // Call the kernel driver to reset the device to a known state.
910 //
911
912 if (EngDeviceIoControl(ppdev->hDriver,
913 IOCTL_VIDEO_RESET_DEVICE,
914 NULL,
915 0,
916 NULL,
917 0,
918 &ulReturn))
919 {
920 DISPDBG((0, "DISP DrvAssertMode failed IOCTL\n"));
921 return FALSE;
922 }
923 else
924 {
925 return TRUE;
926 }
927 }
928}
929
930/******************************Public*Routine******************************\
931* DrvGetModes
932*
933* Returns the list of available modes for the device.
934*
935\**************************************************************************/
936
937ULONG DrvGetModes(
938HANDLE hDriver,
939ULONG cjSize,
940DEVMODEW *pdm)
941
942{
943
944 DWORD cModes;
945 DWORD cbOutputSize;
946 PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
947 DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
948 DWORD cbModeSize;
949
950 DISPDBG((3, "DrvGetModes\n"));
951
952 cModes = getAvailableModes(hDriver,
953 (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
954 &cbModeSize);
955
956 if (cModes == 0)
957 {
958 DISPDBG((0, "DrvGetModes failed to get mode information"));
959 return 0;
960 }
961
962 if (pdm == NULL)
963 {
964 cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
965 }
966 else
967 {
968 //
969 // Now copy the information for the supported modes back into the output
970 // buffer
971 //
972
973 cbOutputSize = 0;
974
975 pVideoTemp = pVideoModeInformation;
976
977 do
978 {
979 if (pVideoTemp->Length != 0)
980 {
981 if (cOutputModes == 0)
982 {
983 break;
984 }
985
986 //
987 // Zero the entire structure to start off with.
988 //
989
990 memset(pdm, 0, sizeof(DEVMODEW));
991
992 //
993 // Set the name of the device to the name of the DLL.
994 //
995
996 memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
997
998 pdm->dmSpecVersion = DM_SPECVERSION;
999 pdm->dmDriverVersion = DM_SPECVERSION;
1000 pdm->dmSize = sizeof(DEVMODEW);
1001 pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
1002
1003 pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
1004 pVideoTemp->BitsPerPlane;
1005 pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
1006 pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
1007 pdm->dmDisplayFrequency = pVideoTemp->Frequency;
1008 pdm->dmDisplayFlags = 0;
1009
1010 pdm->dmFields = DM_BITSPERPEL |
1011 DM_PELSWIDTH |
1012 DM_PELSHEIGHT |
1013 DM_DISPLAYFREQUENCY |
1014 DM_DISPLAYFLAGS ;
1015
1016 //
1017 // Go to the next DEVMODE entry in the buffer.
1018 //
1019
1020 cOutputModes--;
1021
1022 pdm = (LPDEVMODEW) ( ((ULONG_PTR)pdm) + sizeof(DEVMODEW)
1023 + DRIVER_EXTRA_SIZE);
1024
1025 cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
1026
1027 }
1028
1029 pVideoTemp = (PVIDEO_MODE_INFORMATION)
1030 (((PUCHAR)pVideoTemp) + cbModeSize);
1031
1032 } while (--cModes);
1033 }
1034
1035 EngFreeMem(pVideoModeInformation);
1036
1037 return cbOutputSize;
1038
1039}
1040
1041VOID DrvSynchronize(
1042IN DHPDEV dhpdev,
1043IN RECTL *prcl)
1044{
1045}
1046
1047/******************************Public*Routine******************************\
1048* DrvNotify
1049*
1050* Called by GDI to notify us of certain "interesting" events
1051*
1052* DN_DEVICE_ORIGIN is used to communicate the X/Y offsets of individual monitors
1053* when DualView is in effect.
1054*
1055\**************************************************************************/
1056
1057VOID DrvNotify(
1058SURFOBJ *pso,
1059ULONG iType,
1060PVOID pvData)
1061{
1062 PDEV* ppdev = (PDEV*) pso->dhpdev;
1063
1064 DISPDBG((0, "VBoxDisp::DrvNotify called.\n"));
1065
1066 switch(iType)
1067 {
1068 case DN_DEVICE_ORIGIN:
1069 ppdev->ptlDevOrg = *(PPOINTL)pvData;
1070 DISPDBG((3, "DN_DEVICE_ORIGIN: %d, %d (PSO = %p, pInfo = %p)\n", ppdev->ptlDevOrg.x,
1071 ppdev->ptlDevOrg.y, pso, ppdev->pInfo));
1072 if (ppdev->pInfo)
1073 {
1074 ppdev->pInfo->screen.xOrigin = ppdev->ptlDevOrg.x;
1075 ppdev->pInfo->screen.yOrigin = ppdev->ptlDevOrg.y;
1076 VBoxProcessDisplayInfo(ppdev);
1077 }
1078 break;
1079 case DN_DRAWING_BEGIN:
1080 DISPDBG((3, "DN_DRAWING_BEGIN (PSO = %p)\n", pso));
1081 break;
1082 }
1083}
1084
1085#ifdef VBOX_WITH_DDRAW
1086//--------------------------Public Routine-------------------------------------
1087//
1088// HBITMAP DrvDeriveSurface
1089//
1090// This function derives and creates a GDI surface from the specified
1091// DirectDraw surface.
1092//
1093// Parameters
1094// pDirectDraw-----Points to a DD_DIRECTDRAW_GLOBAL structure that describes
1095// the DirectDraw object.
1096// pSurface--------Points to a DD_SURFACE_LOCAL structure that describes the
1097// DirectDraw surface around which to wrap a GDI surface.
1098//
1099// Return Value
1100// DrvDeriveSurface returns a handle to the created GDI surface upon success.
1101// It returns NULL if the call fails or if the driver cannot accelerate GDI
1102// drawing to the specified DirectDraw surface.
1103//
1104// Comments
1105// DrvDeriveSurface allows the driver to create a GDI surface around a
1106// DirectDraw video memory or AGP surface object in order to allow accelerated
1107// GDI drawing to the surface. If the driver does not hook this call, all GDI
1108// drawing to DirectDraw surfaces is done in software using the DIB engine.
1109//
1110// GDI calls DrvDeriveSurface with RGB surfaces only.
1111//
1112// The driver should call DrvCreateDeviceBitmap to create a GDI surface of the
1113// same size and format as that of the DirectDraw surface. Space for the
1114// actual pixels need not be allocated since it already exists.
1115//
1116//-----------------------------------------------------------------------------
1117HBITMAP DrvDeriveSurface(DD_DIRECTDRAW_GLOBAL* pDirectDraw, DD_SURFACE_LOCAL* pSurface)
1118{
1119 PPDEV pDev = (PPDEV)pDirectDraw->dhpdev;
1120// HBITMAP hbmDevice;
1121 DD_SURFACE_GLOBAL* pSurfaceGlobal;
1122// SIZEL sizl;
1123
1124 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1125
1126 pSurfaceGlobal = pSurface->lpGbl;
1127
1128 //
1129 // GDI should never call us for a non-RGB surface, but let's assert just
1130 // to make sure they're doing their job properly.
1131 //
1132 AssertMsg(!(pSurfaceGlobal->ddpfSurface.dwFlags & DDPF_FOURCC), ("GDI called us with a non-RGB surface!"));
1133
1134#if 0
1135 // The GDI driver does not accelerate surfaces in AGP memory,
1136 // thus we fail the call
1137
1138 if (pSurface->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
1139 {
1140 DISPDBG((0, "DrvDeriveSurface return NULL, surface in AGP memory"));
1141 return 0;
1142 }
1143
1144 // The GDI driver does not accelerate managed surface,
1145 // thus we fail the call
1146 if (pSurface->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
1147 {
1148 DISPDBG((0, "DrvDeriveSurface return NULL, surface is managed"));
1149 return 0;
1150 }
1151
1152 //
1153 // The rest of our driver expects GDI calls to come in with the same
1154 // format as the primary surface. So we'd better not wrap a device
1155 // bitmap around an RGB format that the rest of our driver doesn't
1156 // understand. Also, we must check to see that it is not a surface
1157 // whose pitch does not match the primary surface.
1158 //
1159 // NOTE: Most surfaces created by this driver are allocated as 2D surfaces
1160 // whose lPitch's are equal to the screen pitch. However, overlay surfaces
1161 // are allocated such that there lPitch's are usually different then the
1162 // screen pitch. The hardware can not accelerate drawing operations to
1163 // these surfaces and thus we fail to derive these surfaces.
1164 //
1165 if ( (pSurfaceGlobal->ddpfSurface.dwRGBBitCount == pDev->ulBitCount) )
1166 {
1167 SIZEL sizel;
1168 DWORD ulBitmapType, flHooks;
1169
1170 sizl.cx = pSurfaceGlobal->wWidth;
1171 sizl.cy = pSurfaceGlobal->wHeight;
1172
1173 if (pDev->ulBitCount == 8)
1174 {
1175 if (!bInit256ColorPalette(pDev)) {
1176 DISPDBG((0, "DISP DrvEnableSurface failed to init the 8bpp palette\n"));
1177 return(FALSE);
1178 }
1179 ulBitmapType = BMF_8BPP;
1180 flHooks = HOOKS_BMF8BPP;
1181 }
1182 else if (pDev->ulBitCount == 16)
1183 {
1184 ulBitmapType = BMF_16BPP;
1185 flHooks = HOOKS_BMF16BPP;
1186 }
1187 else if (pDev->ulBitCount == 24)
1188 {
1189 ulBitmapType = BMF_24BPP;
1190 flHooks = HOOKS_BMF24BPP;
1191 }
1192 else
1193 {
1194 ulBitmapType = BMF_32BPP;
1195 flHooks = HOOKS_BMF32BPP;
1196 }
1197
1198 hbmDevice = EngCreateBitmap(sizl,
1199 pDev->lDeltaScreen,
1200 ulBitmapType,
1201 (pDev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0,
1202 (PVOID) (pDev->pjScreen));
1203 if (hbmDevice)
1204 {
1205 VOID* pvScan0 = pDev->pjScreen + pSurfaceGlobal->fpVidMem;
1206
1207 //
1208 // Note that HOOK_SYNCHRONIZE must always be hooked when we
1209 // give GDI a pointer to the bitmap bits. We don't need to
1210 // do it here since HOOK_SYNCHRONIZE is always set in our
1211 // pdev->flHooks
1212 //
1213 ULONG flags = MS_NOTSYSTEMMEMORY;
1214
1215 if ( EngModifySurface((HSURF)hbmDevice,
1216 pDev->hdevEng,
1217 pDev->flHooks,
1218 flags,
1219 (DHSURF)hbmDevice,
1220 pvScan0,
1221 pSurfaceGlobal->lPitch,
1222 NULL) )
1223 {
1224 SURFOBJ* surfobj = EngLockSurface((HSURF) hbmDevice);
1225 AssertMsg(surfobj->iType == STYPE_BITMAP, ("expected STYPE_BITMAP"));
1226 surfobj->iType = STYPE_DEVBITMAP;
1227 EngUnlockSurface(surfobj);
1228
1229 DISPDBG((0, "DrvDeriveSurface return succeed"));
1230 return(hbmDevice);
1231 }
1232
1233 DISPDBG((0, "DrvDeriveSurface: EngModifySurface failed"));
1234 EngDeleteSurface((HSURF)hbmDevice);
1235 }
1236 }
1237
1238 DISPDBG((0, "DrvDeriveSurface return NULL"));
1239 DISPDBG((0, "pSurfaceGlobal->ddpfSurface.dwRGBBitCount = %d, lPitch =%ld", pSurfaceGlobal->ddpfSurface.dwRGBBitCount,pSurfaceGlobal->lPitch));
1240#endif
1241
1242 return(0);
1243}
1244#endif /* VBOX_WITH_DDRAW */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette