Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4200 lines
124 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: object.c *
  3. * *
  4. * GDI client side stubs which deal with object creation and deletion. *
  5. * *
  6. * Created: 30-May-1991 21:56:51 *
  7. * Author: Charles Whitmer [chuckwh] *
  8. * *
  9. * Copyright (c) 1991-1999 Microsoft Corporation *
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. extern PGDIHANDLECACHE pGdiHandleCache;
  14. ULONG gLoHandleType[GDI_CACHED_HADNLE_TYPES] = {
  15. LO_BRUSH_TYPE ,
  16. LO_PEN_TYPE ,
  17. LO_REGION_TYPE ,
  18. LO_FONT_TYPE
  19. };
  20. ULONG gHandleCacheSize[GDI_CACHED_HADNLE_TYPES] = {
  21. CACHE_BRUSH_ENTRIES ,
  22. CACHE_PEN_ENTRIES ,
  23. CACHE_REGION_ENTRIES,
  24. CACHE_LFONT_ENTRIES
  25. };
  26. ULONG gCacheHandleOffsets[GDI_CACHED_HADNLE_TYPES] = {
  27. 0,
  28. CACHE_BRUSH_ENTRIES,
  29. (
  30. CACHE_BRUSH_ENTRIES +
  31. CACHE_PEN_ENTRIES
  32. ),
  33. (
  34. CACHE_BRUSH_ENTRIES +
  35. CACHE_PEN_ENTRIES +
  36. CACHE_PEN_ENTRIES
  37. )
  38. };
  39. /******************************Public*Routine******************************\
  40. * hGetPEBHandle
  41. *
  42. * Try to allocate a handle from the PEB handle cache
  43. *
  44. * Aruguments:
  45. *
  46. * HandleType - type of cached handle to allocate
  47. *
  48. * Return Value:
  49. *
  50. * handle or NULL if none available
  51. *
  52. * History:
  53. *
  54. * 31-Jan-1996 -by- Mark Enstrom [marke]
  55. *
  56. \**************************************************************************/
  57. HANDLE
  58. hGetPEBHandle(
  59. HANDLECACHETYPE HandleType,
  60. ULONG lbColor
  61. )
  62. {
  63. HANDLE hret = NULL;
  64. BOOL bStatus;
  65. PBRUSHATTR pBrushattr;
  66. OBJTYPE ObjType = BRUSH_TYPE;
  67. #if !defined(_GDIPLUS_)
  68. ASSERTGDI(
  69. (
  70. (HandleType == BrushHandle) ||
  71. (HandleType == PenHandle) ||
  72. (HandleType == RegionHandle) ||
  73. (HandleType == LFontHandle)
  74. ),
  75. "hGetPEBHandle: illegal handle type");
  76. if (HandleType == RegionHandle)
  77. {
  78. ObjType = RGN_TYPE;
  79. }
  80. LOCK_HANDLE_CACHE(pGdiHandleCache,NtCurrentTeb(),bStatus);
  81. if (bStatus)
  82. {
  83. //
  84. // is a handle of the requested type available
  85. //
  86. if (pGdiHandleCache->ulNumHandles[HandleType] > 0)
  87. {
  88. ULONG Index = gCacheHandleOffsets[HandleType];
  89. KHANDLE *pHandle,*pMaxHandle;
  90. //
  91. // calc starting index of handle type in PEB,
  92. // convert to address for faster linear search
  93. //
  94. pHandle = &(pGdiHandleCache->Handle[Index]);
  95. pMaxHandle = pHandle + gHandleCacheSize[HandleType];
  96. //
  97. // search PEB for non-NULL handle of th correct type
  98. //
  99. while (pHandle != pMaxHandle)
  100. {
  101. if (*pHandle != NULL)
  102. {
  103. hret = *pHandle;
  104. ASSERTGDI((gLoHandleType[HandleType] == LO_TYPE((ULONG_PTR)hret)),
  105. "hGetPEBHandle: handle LO_TYPE mismatch");
  106. *pHandle = NULL;
  107. pGdiHandleCache->ulNumHandles[HandleType]--;
  108. PSHARED_GET_VALIDATE(pBrushattr,hret,ObjType);
  109. //
  110. // setup the fields
  111. //
  112. if (
  113. (pBrushattr) &&
  114. ((pBrushattr->AttrFlags & (ATTR_CACHED | ATTR_TO_BE_DELETED | ATTR_CANT_SELECT))
  115. == ATTR_CACHED)
  116. )
  117. {
  118. //
  119. // set brush flag which indicates this brush
  120. // has never been selected into a dc. if this flag
  121. // is still set in deleteobject then it is ok to
  122. // put the brush on the teb.
  123. //
  124. pBrushattr->AttrFlags &= ~ATTR_CACHED;
  125. if ((HandleType == BrushHandle) && (pBrushattr->lbColor != lbColor))
  126. {
  127. pBrushattr->AttrFlags |= ATTR_NEW_COLOR;
  128. pBrushattr->lbColor = lbColor;
  129. }
  130. }
  131. else
  132. {
  133. //
  134. // Bad brush on PEB
  135. //
  136. WARNING ("pBrushattr == NULL, bad handle on TEB/PEB! \n");
  137. //DeleteObject(hbr);
  138. hret = NULL;
  139. }
  140. break;
  141. }
  142. pHandle++;
  143. }
  144. }
  145. UNLOCK_HANDLE_CACHE(pGdiHandleCache);
  146. }
  147. #endif
  148. return(hret);
  149. }
  150. /******************************Public*Routine******************************\
  151. * GdiPlayJournal
  152. *
  153. * Plays a journal file to an hdc.
  154. *
  155. * History:
  156. * 31-Mar-1992 -by- Patrick Haluptzok patrickh
  157. * Wrote it.
  158. \**************************************************************************/
  159. BOOL WINAPI GdiPlayJournal
  160. (
  161. HDC hDC,
  162. LPWSTR pwszName,
  163. DWORD iStart,
  164. DWORD iEnd,
  165. int iDeltaPriority
  166. )
  167. {
  168. WARNING("GdiPlayJournalCalled but no longer implemented\n");
  169. return(FALSE);
  170. }
  171. /******************************Public*Routine******************************\
  172. * gdiPlaySpoolStream
  173. *
  174. * Stub of Chicago version of GdiPlayJournal
  175. *
  176. * History:
  177. * 4-29-95 Gerrit van Wingerden
  178. * Wrote it.
  179. \**************************************************************************/
  180. HDC gdiPlaySpoolStream(
  181. LPSTR lpszDevice,
  182. LPSTR lpszOutput,
  183. LPSTR lpszSpoolFile,
  184. DWORD JobId,
  185. LPDWORD lpcbBuf,
  186. HDC hDC )
  187. {
  188. USE(lpszDevice);
  189. USE(lpszOutput);
  190. USE(lpszSpoolFile);
  191. USE(JobId);
  192. USE(lpcbBuf);
  193. USE(hDC);
  194. GdiSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  195. return(hDC);
  196. }
  197. /******************************Public*Routine******************************\
  198. *
  199. * History:
  200. * 08-Nov-1994 -by- Eric Kutter [erick]
  201. * Wrote it.
  202. \**************************************************************************/
  203. NTSTATUS
  204. PrinterQueryRoutine
  205. (
  206. IN PWSTR ValueName,
  207. IN ULONG ValueType,
  208. IN PVOID ValueData,
  209. IN ULONG ValueLength,
  210. IN PVOID Context,
  211. IN PVOID EntryContext
  212. )
  213. {
  214. //
  215. // If the context value is NULL, then store the length of the value.
  216. // Otherwise, copy the value to the specified memory.
  217. //
  218. if (Context == NULL)
  219. {
  220. *(PULONG)EntryContext = ValueLength;
  221. }
  222. else
  223. {
  224. RtlCopyMemory(Context, ValueData, (int)ValueLength);
  225. }
  226. return(STATUS_SUCCESS);
  227. }
  228. /******************************Public*Routine******************************\
  229. * pdmwGetDefaultDevMode()
  230. *
  231. * History:
  232. * 08-Nov-1994 -by- Eric Kutter [erick]
  233. * Wrote it.
  234. \**************************************************************************/
  235. PDEVMODEW pdmwGetDefaultDevMode(
  236. HANDLE hSpooler,
  237. PUNICODE_STRING pustrDevice, // device name
  238. PVOID *ppvFree // *ppvFree must be freed by the caller
  239. )
  240. {
  241. PDEVMODEW pdmw = NULL;
  242. int cj;
  243. PWSZ pwszDevice = pustrDevice ? pustrDevice->Buffer : NULL;
  244. // see if we found it in the registry. If not, we need to get the default from
  245. // the spooler.
  246. cj = 0;
  247. (*fpGetPrinterW)(hSpooler,2,NULL,0,&cj);
  248. if (cj && (*ppvFree = LOCALALLOC(cj)))
  249. {
  250. // we've loaded the spooler, gotten a spooler handle, gotten the size,
  251. // and allocated the buffer. Now lets get the data.
  252. if ((*fpGetPrinterW)(hSpooler,2,*ppvFree,cj,&cj))
  253. {
  254. pdmw = ((PRINTER_INFO_2W *)*ppvFree)->pDevMode;
  255. }
  256. else
  257. {
  258. LOCALFREE(*ppvFree);
  259. *ppvFree = NULL;
  260. }
  261. }
  262. return(pdmw);
  263. }
  264. /******************************Public*Routine******************************\
  265. * hdcCreateDCW *
  266. * *
  267. * Client side stub. Allocates a client side LDC as well. *
  268. * *
  269. * Note that it calls the server only after all client side stuff has *
  270. * succeeded, we don't want to ask the server to clean up. *
  271. * *
  272. * History: *
  273. * Sat 01-Jun-1991 16:13:22 -by- Charles Whitmer [chuckwh] *
  274. * 8-18-92 Unicode enabled and combined with CreateIC *
  275. * Wrote it. *
  276. \**************************************************************************/
  277. HDC hdcCreateDCW(
  278. PUNICODE_STRING pustrDevice,
  279. PUNICODE_STRING pustrPort,
  280. CONST DEVMODEW *pdm,
  281. BOOL bDisplay,
  282. BOOL bIC
  283. )
  284. {
  285. HDC hdc = NULL;
  286. PLDC pldc = NULL;
  287. PVOID pvFree = NULL;
  288. PWSZ pwszPort = NULL;
  289. HANDLE hSpooler = NULL;
  290. PUMPD pUMPD = NULL;
  291. PDEVMODEW pdmAlt = NULL;
  292. PRINTER_DEFAULTSW defaults;
  293. KERNEL_PUMDHPDEV pUMdhpdev = NULL;
  294. BOOL bDocEvent = FALSE;
  295. //
  296. // if it is not the display...
  297. //
  298. if (!bDisplay)
  299. {
  300. //
  301. // quick out if pustrDevice is NULL
  302. //
  303. if (pustrDevice == (PUNICODE_STRING)NULL)
  304. {
  305. return((HDC)NULL);
  306. }
  307. // Load the spooler and get a spool handle
  308. if (BLOADSPOOLER)
  309. {
  310. // Open the printer with the default data type. When we do
  311. // a StartDoc we will then try to to a StartDocPrinter with data type
  312. // EMF if that suceeds will will mark the DC as an EMF dc. Othewise
  313. // we will try again, this time doing a StartDocPrinter with data type
  314. // raw
  315. defaults.pDevMode = (LPDEVMODEW) pdm;
  316. defaults.DesiredAccess = PRINTER_ACCESS_USE;
  317. defaults.pDatatype = L"RAW";
  318. // open the spooler and note if it is spooled or not
  319. (*fpOpenPrinterW)((LPWSTR)pustrDevice->Buffer,&hSpooler,&defaults);
  320. if (hSpooler)
  321. {
  322. // Load user-mode printer driver, if applicable
  323. if (! LoadUserModePrinterDriver(hSpooler, (LPWSTR) pustrDevice->Buffer, &pUMPD, &defaults))
  324. goto MSGERROR;
  325. // and we don't have a devmode yet, try to get one.
  326. if (pdm == NULL)
  327. {
  328. pdm = pdmwGetDefaultDevMode(hSpooler,pustrDevice,&pvFree);
  329. }
  330. // now see if we need to call DocumentEvent
  331. if (fpDocumentEvent)
  332. {
  333. int iDocEventRet;
  334. DOCEVENT_CREATEDCPRE docEvent;
  335. docEvent.pszDriver = 0;
  336. docEvent.pszDevice = pustrDevice->Buffer;
  337. docEvent.pdm = (PDEVMODEW)pdm;
  338. docEvent.bIC = bIC;
  339. iDocEventRet = DocumentEventEx(pUMPD,
  340. hSpooler,
  341. 0,
  342. DOCUMENTEVENT_CREATEDCPRE,
  343. sizeof(docEvent),
  344. (PVOID)&docEvent,
  345. sizeof(pdmAlt),
  346. (PVOID)&pdmAlt);
  347. if (iDocEventRet == DOCUMENTEVENT_FAILURE)
  348. {
  349. goto MSGERROR;
  350. }
  351. bDocEvent = TRUE;
  352. if (pdmAlt)
  353. pdm = pdmAlt;
  354. }
  355. }
  356. }
  357. }
  358. hdc = NtGdiOpenDCW(pustrDevice,
  359. (PDEVMODEW)pdm,
  360. pustrPort,
  361. (ULONG)bIC ? DCTYPE_INFO : DCTYPE_DIRECT,
  362. (pUMPD == NULL) ? NULL : hSpooler,
  363. (pUMPD == NULL) ? NULL : pUMPD->pDriverInfo2,
  364. &pUMdhpdev);
  365. if (hdc)
  366. {
  367. //
  368. // The only way it could be an ALTDC at this point is to be a
  369. // printer DC
  370. //
  371. if (IS_ALTDC_TYPE(hdc) && hSpooler)
  372. {
  373. pldc = pldcCreate(hdc,LO_DC);
  374. if (!pldc)
  375. {
  376. goto MSGERROR;
  377. }
  378. // Need to save DEVMODE in client side for later use.
  379. if (pdm)
  380. {
  381. ULONG cjDevMode = pdm->dmSize + pdm->dmDriverExtra;
  382. pldc->pDevMode = (DEVMODEW*) LOCALALLOC(cjDevMode);
  383. if (pldc->pDevMode == NULL)
  384. {
  385. goto MSGERROR;
  386. }
  387. // Validate DEVMMODE, then copy to buffer.
  388. if ((pdm->dmSize >= offsetof(DEVMODEW,dmDuplex)) &&
  389. (pdm->dmFields & DM_COLOR) &&
  390. (pdm->dmColor == DMCOLOR_MONOCHROME))
  391. {
  392. // if devmode says, this is monochrome mode, we don't need to
  393. // validate devmode since this validation is for ICM which
  394. // only needs for color case. Just copy whatever apps gives us.
  395. RtlCopyMemory( (PBYTE) pldc->pDevMode, (PBYTE) pdm, cjDevMode );
  396. }
  397. else if ((*fpDocumentPropertiesW)
  398. (NULL,hSpooler,
  399. (LPWSTR) pdm->dmDeviceName,
  400. pldc->pDevMode, // output devmode
  401. (PDEVMODEW) pdm, // input devmode
  402. DM_IN_BUFFER |
  403. DM_OUT_BUFFER) != IDOK)
  404. {
  405. // if error, just copy original
  406. RtlCopyMemory( (PBYTE) pldc->pDevMode, (PBYTE) pdm, cjDevMode );
  407. }
  408. }
  409. pldc->hSpooler = hSpooler;
  410. pldc->pUMPD = pUMPD;
  411. pldc->pUMdhpdev = pUMdhpdev;
  412. //
  413. // if the UMPD driver is first loaded
  414. // and no one has set either the METAFILE_DRIVER nor the NON_METAFILE_DRIVER flag,
  415. // set it here
  416. //
  417. if (pUMPD)
  418. {
  419. if (!(pldc->pUMPD->dwFlags & UMPDFLAG_NON_METAFILE_DRIVER)
  420. && !(pldc->pUMPD->dwFlags & UMPDFLAG_METAFILE_DRIVER))
  421. {
  422. ULONG InData = METAFILE_DRIVER;
  423. if (ExtEscape(hdc,QUERYESCSUPPORT,sizeof(ULONG),(LPCSTR)&InData,0,NULL))
  424. {
  425. pldc->pUMPD->dwFlags |= UMPDFLAG_METAFILE_DRIVER;
  426. }
  427. else
  428. {
  429. pldc->pUMPD->dwFlags |= UMPDFLAG_NON_METAFILE_DRIVER;
  430. }
  431. }
  432. }
  433. // remember if it is an IC
  434. if (bIC)
  435. pldc->fl |= LDC_INFO;
  436. // Initialize ICM stuff for this DC.
  437. //
  438. // (if pdem is substituted by DrvDocumentEvent,
  439. // use the substituted devmode).
  440. IcmInitLocalDC(hdc,hSpooler,pdm,FALSE);
  441. // got to save the port name for StartDoc();
  442. if (pustrPort)
  443. {
  444. int cj = pustrPort->Length + sizeof(WCHAR);
  445. pldc->pwszPort = (LPWSTR)LOCALALLOC(cj);
  446. if (pldc->pwszPort)
  447. memcpy(pldc->pwszPort,pustrPort->Buffer,cj);
  448. }
  449. // we need to do the CREATEDCPOST document event
  450. DocumentEventEx(pldc->pUMPD,
  451. hSpooler,
  452. hdc,
  453. DOCUMENTEVENT_CREATEDCPOST,
  454. sizeof(pdmAlt),
  455. (PVOID)&pdmAlt,
  456. 0,
  457. NULL);
  458. }
  459. else
  460. {
  461. // Initialize ICM stuff for this DC.
  462. IcmInitLocalDC(hdc,NULL,pdm,FALSE);
  463. if (pwszPort)
  464. LOCALFREE(pwszPort);
  465. }
  466. }
  467. else
  468. {
  469. // Handle errors.
  470. MSGERROR:
  471. if (hSpooler)
  472. {
  473. if (bDocEvent)
  474. {
  475. DocumentEventEx(pUMPD,
  476. hSpooler,
  477. 0,
  478. DOCUMENTEVENT_CREATEDCPOST,
  479. sizeof(pdmAlt),
  480. (PVOID)&pdmAlt,
  481. 0,
  482. NULL);
  483. }
  484. if (pUMPD)
  485. UnloadUserModePrinterDriver(pUMPD, TRUE, hSpooler);
  486. (*fpClosePrinter)(hSpooler);
  487. }
  488. if (pwszPort)
  489. LOCALFREE(pwszPort);
  490. if (pldc)
  491. bDeleteLDC(pldc);
  492. if (hdc)
  493. NtGdiDeleteObjectApp(hdc);
  494. hdc = (HDC)0;
  495. }
  496. if (pvFree != NULL)
  497. {
  498. LOCALFREE(pvFree);
  499. }
  500. return(hdc);
  501. }
  502. /******************************Public*Routine******************************\
  503. * bCreateDCW *
  504. * *
  505. * Client side stub. Allocates a client side LDC as well. *
  506. * *
  507. * Note that it calls the server only after all client side stuff has *
  508. * succeeded, we don't want to ask the server to clean up. *
  509. * *
  510. * History: *
  511. * Sat 01-Jun-1991 16:13:22 -by- Charles Whitmer [chuckwh] *
  512. * 8-18-92 Unicode enabled and combined with CreateIC *
  513. * Wrote it. *
  514. \**************************************************************************/
  515. CONST WCHAR gwszDisplayDevice[] = L"\\\\.\\DISPLAY";
  516. HDC bCreateDCW
  517. (
  518. LPCWSTR pszDriver,
  519. LPCWSTR pszDevice,
  520. LPCWSTR pszPort ,
  521. CONST DEVMODEW *pdm,
  522. BOOL bIC
  523. )
  524. {
  525. UNICODE_STRING ustrDevice;
  526. UNICODE_STRING ustrPort;
  527. PUNICODE_STRING pustrDevice = NULL;
  528. PUNICODE_STRING pustrPort = NULL;
  529. BOOL bDisplay = FALSE;
  530. // check for multi-monitor cases, first.
  531. if (pszDevice != NULL)
  532. {
  533. if (_wcsnicmp(pszDevice,
  534. gwszDisplayDevice,
  535. ((sizeof(gwszDisplayDevice)/sizeof(WCHAR))-1)) == 0)
  536. {
  537. // CreateDC(?, L"\\.\DISPLAY?",...);
  538. // (this case, we don't care whatever passed into pszDriver)
  539. //
  540. // if apps call, CreateDC("DISPLAY","\\.\DISPLAY?",...);,
  541. // we handle this as multi-monitor case. that's why
  542. // we check multi-monitor case first.
  543. bDisplay = TRUE;
  544. }
  545. }
  546. // check for most typical case to create display DC
  547. if (!bDisplay && (pszDriver != NULL))
  548. {
  549. if (_wcsicmp(pszDriver,(LPWSTR)L"DISPLAY") == 0)
  550. {
  551. // CreateDC(L"DISPLAY",?,...);
  552. //
  553. // Comments Win9x [gdi\dcman1.asm]
  554. //
  555. // This fix is for people who called CreateDC/IC with
  556. // ("Display","Display", xxxxx) rather than ("Display",
  557. // NULL, NULL) which it was supposed to.
  558. //
  559. // NULL to pszDevice.
  560. pszDevice = NULL;
  561. bDisplay = TRUE;
  562. }
  563. }
  564. // check for memphis compatibility
  565. if (!bDisplay && (pszDriver != NULL))
  566. {
  567. // The comment and code from Memphis.
  568. //
  569. // // the normal syntax apps will use is
  570. // //
  571. // // CreateDC(NULL, "\\.\DisplayX", ...)
  572. // //
  573. // // but USER uses this syntax, so we will support it too.
  574. // //
  575. // // CreateDC("\\.\DisplayX", NULL, ...)
  576. // //
  577. // if (lpDriverName != NULL && *(DWORD FAR *)lpDriverName == 0x5C2E5C5C)
  578. // {
  579. // lpDeviceName = lpDriverName;
  580. // lpDriverName = NULL;
  581. // }
  582. if (_wcsnicmp(pszDriver,
  583. gwszDisplayDevice,
  584. ((sizeof(gwszDisplayDevice)/sizeof(WCHAR))-1)) == 0)
  585. {
  586. pszDevice = pszDriver;
  587. bDisplay = TRUE;
  588. }
  589. }
  590. // convert the strings
  591. if (pszDevice)
  592. {
  593. RtlInitUnicodeString(&ustrDevice,pszDevice);
  594. pustrDevice = &ustrDevice;
  595. }
  596. if (pszPort)
  597. {
  598. RtlInitUnicodeString(&ustrPort,pszPort);
  599. pustrPort = &ustrPort;
  600. }
  601. // call the common stub
  602. return(hdcCreateDCW(pustrDevice,pustrPort,pdm,bDisplay,bIC));
  603. }
  604. /******************************Public*Routine******************************\
  605. * bCreateDCA
  606. *
  607. * Client side stub. Allocates a client side LDC as well.
  608. *
  609. *
  610. * Note that it calls the server only after all client side stuff has
  611. * succeeded, we don't want to ask the server to clean up.
  612. *
  613. * History:
  614. * 8-18-92 Gerrit van Wingerden
  615. * Wrote it.
  616. \**************************************************************************/
  617. CONST CHAR gszDisplayDevice[] = "\\\\.\\DISPLAY";
  618. HDC bCreateDCA
  619. (
  620. LPCSTR pszDriver,
  621. LPCSTR pszDevice,
  622. LPCSTR pszPort ,
  623. LPDEVMODEA pdm,
  624. BOOL bIC
  625. )
  626. {
  627. HDC hdcRet = 0;
  628. UNICODE_STRING ustrDevice;
  629. UNICODE_STRING ustrPort;
  630. PUNICODE_STRING pustrDevice = NULL;
  631. PUNICODE_STRING pustrPort = NULL;
  632. DEVMODEW *pdmw = NULL;
  633. BOOL bDisplay = FALSE;
  634. // check for multi-monitor cases, first.
  635. if (pszDevice != NULL)
  636. {
  637. if (_strnicmp(pszDevice,
  638. gszDisplayDevice,
  639. ((sizeof(gszDisplayDevice)/sizeof(CHAR))-1)) == 0)
  640. {
  641. // CreateDC(?,"\\.\DISPLAY?",...);
  642. // (this case, we don't care whatever passed into pszDriver)
  643. //
  644. // if apps call, CreateDC("DISPLAY","\\.\DISPLAY?",...);,
  645. // we handle this as multi-monitor case. that's why
  646. // we check multi-monitor case first.
  647. bDisplay = TRUE;
  648. }
  649. }
  650. // check for most typical case to create display DC
  651. if (!bDisplay && (pszDriver != NULL))
  652. {
  653. if (_stricmp(pszDriver,"DISPLAY") == 0)
  654. {
  655. // CreateDC("DISPLAY",?,...);
  656. //
  657. // Comments Win9x [gdi\dcman1.asm]
  658. //
  659. // This fix is for people who called CreateDC/IC with
  660. // ("Display","Display", xxxxx) rather than ("Display",
  661. // NULL, NULL) which it was supposed to.
  662. //
  663. // NULL to pszDevice.
  664. pszDevice = NULL;
  665. bDisplay = TRUE;
  666. }
  667. }
  668. // check for memphis compatibility
  669. if (!bDisplay && (pszDriver != NULL))
  670. {
  671. // The comment and code from Memphis.
  672. //
  673. // // the normal syntax apps will use is
  674. // //
  675. // // CreateDC(NULL, "\\.\DisplayX", ...)
  676. // //
  677. // // but USER uses this syntax, so we will support it too.
  678. // //
  679. // // CreateDC("\\.\DisplayX", NULL, ...)
  680. // //
  681. // if (lpDriverName != NULL && *(DWORD FAR *)lpDriverName == 0x5C2E5C5C)
  682. // {
  683. // lpDeviceName = lpDriverName;
  684. // lpDriverName = NULL;
  685. // }
  686. if (_strnicmp(pszDriver,
  687. gszDisplayDevice,
  688. ((sizeof(gszDisplayDevice)/sizeof(CHAR))-1)) == 0)
  689. {
  690. pszDevice = pszDriver;
  691. bDisplay = TRUE;
  692. }
  693. }
  694. // convert the strings
  695. if (pszDevice)
  696. {
  697. // [NOTE:]
  698. // RtlCreateUnicodeStringFromAsciiz() returns boolean, NOT NTSTATUS !
  699. if (!RtlCreateUnicodeStringFromAsciiz(&ustrDevice,pszDevice))
  700. {
  701. goto MSGERROR;
  702. }
  703. pustrDevice = &ustrDevice;
  704. }
  705. if (pszPort)
  706. {
  707. // [NOTE:]
  708. // RtlCreateUnicodeStringFromAsciiz() returns boolean, NOT NTSTATUS !
  709. if (!RtlCreateUnicodeStringFromAsciiz(&ustrPort,pszPort))
  710. {
  711. goto MSGERROR;
  712. }
  713. pustrPort = &ustrPort;
  714. }
  715. // if it is a display, don't use the devmode if the dmDeviceName is empty
  716. if (pdm != NULL)
  717. {
  718. if (!bDisplay || (pdm->dmDeviceName[0] != 0))
  719. {
  720. pdmw = GdiConvertToDevmodeW(pdm);
  721. if( pdmw == NULL )
  722. goto MSGERROR;
  723. }
  724. }
  725. // call the common stub
  726. hdcRet = hdcCreateDCW(pustrDevice,pustrPort,pdmw,bDisplay,bIC);
  727. // clean up
  728. MSGERROR:
  729. if (pustrDevice)
  730. RtlFreeUnicodeString(pustrDevice);
  731. if (pustrPort)
  732. RtlFreeUnicodeString(pustrPort);
  733. if(pdmw != NULL)
  734. LOCALFREE(pdmw);
  735. return(hdcRet);
  736. }
  737. /******************************Public*Routine******************************\
  738. * CreateICW
  739. *
  740. * wrapper for bCreateDCW
  741. *
  742. * History:
  743. * 8-18-92 Gerrit van Wingerden
  744. * Wrote it.
  745. \**************************************************************************/
  746. HDC WINAPI CreateICW
  747. (
  748. LPCWSTR pwszDriver,
  749. LPCWSTR pwszDevice,
  750. LPCWSTR pwszPort,
  751. CONST DEVMODEW *pdm
  752. )
  753. {
  754. return bCreateDCW( pwszDriver, pwszDevice, pwszPort, pdm, TRUE );
  755. }
  756. /******************************Public*Routine******************************\
  757. * CreateICA
  758. *
  759. * wrapper for bCreateICA
  760. *
  761. * History:
  762. * 8-18-92 Gerrit van Wingerden
  763. * Wrote it.
  764. \**************************************************************************/
  765. HDC WINAPI CreateICA
  766. (
  767. LPCSTR pszDriver,
  768. LPCSTR pszDevice,
  769. LPCSTR pszPort,
  770. CONST DEVMODEA *pdm
  771. )
  772. {
  773. return bCreateDCA( pszDriver, pszDevice, pszPort, (LPDEVMODEA)pdm, TRUE );
  774. }
  775. /******************************Public*Routine******************************\
  776. * CreateDCW
  777. *
  778. * wrapper for bCreateDCA
  779. *
  780. * History:
  781. * 8-18-92 Gerrit van Wingerden
  782. * Wrote it.
  783. \**************************************************************************/
  784. HDC WINAPI CreateDCA
  785. (
  786. LPCSTR pszDriver,
  787. LPCSTR pszDevice,
  788. LPCSTR pszPort,
  789. CONST DEVMODEA *pdm
  790. )
  791. {
  792. return bCreateDCA( pszDriver, pszDevice, pszPort, (LPDEVMODEA)pdm, FALSE );
  793. }
  794. /******************************Public*Routine******************************\
  795. * CreateDCW
  796. *
  797. * wrapper for bCreateDCW
  798. *
  799. * History:
  800. * 8-18-92 Gerrit van Wingerden
  801. * Wrote it.
  802. \**************************************************************************/
  803. HDC WINAPI CreateDCW
  804. (
  805. LPCWSTR pwszDriver,
  806. LPCWSTR pwszDevice,
  807. LPCWSTR pwszPort ,
  808. CONST DEVMODEW *pdm
  809. )
  810. {
  811. return bCreateDCW( pwszDriver, pwszDevice, pwszPort, pdm, FALSE );
  812. }
  813. /******************************Public*Routine******************************\
  814. * GdiConvertToDevmodeW
  815. *
  816. * Converts a DEVMODEA to a DEVMODEW structure
  817. *
  818. * History:
  819. * 09-08-1995 Andre Vachon
  820. * Wrote it.
  821. \**************************************************************************/
  822. LPDEVMODEW
  823. GdiConvertToDevmodeW(
  824. LPDEVMODEA pdma
  825. )
  826. {
  827. DWORD cj;
  828. LPDEVMODEW pdmw;
  829. // Sanity check. We should have at least up to and including the
  830. // dmDriverExtra field of the DEVMODE structure.
  831. //
  832. // NOTE dmSize CAN be greater than the size of the DEVMODE
  833. // structure (not counting driver specific data, of course) because this
  834. // structure grows from version to version.
  835. //
  836. if (pdma->dmSize <= (offsetof(DEVMODEA,dmDriverExtra)))
  837. {
  838. ASSERTGDI(FALSE, "GdiConvertToDevmodeW: DevMode.dmSize bad or corrupt\n");
  839. return(NULL);
  840. }
  841. pdmw = (DEVMODEW *) LOCALALLOC(sizeof(DEVMODEW) + pdma->dmDriverExtra);
  842. if (pdmw)
  843. {
  844. //
  845. // If we get to here, we know we have at least up to and including
  846. // the dmDriverExtra field.
  847. //
  848. vToUnicodeN(pdmw->dmDeviceName,
  849. CCHDEVICENAME,
  850. pdma->dmDeviceName,
  851. CCHDEVICENAME);
  852. pdmw->dmSpecVersion = pdma->dmSpecVersion ;
  853. pdmw->dmDriverVersion = pdma->dmDriverVersion;
  854. pdmw->dmSize = pdma->dmSize + CCHDEVICENAME;
  855. pdmw->dmDriverExtra = pdma->dmDriverExtra;
  856. //
  857. // Anything left in the pdma buffer? Copy any data between the dmDriverExtra
  858. // field and the dmFormName, truncating the amount to the size of the
  859. // pdma buffer (as specified by dmSize), of course.
  860. //
  861. cj = MIN(pdma->dmSize - offsetof(DEVMODEA,dmFields),
  862. offsetof(DEVMODEA,dmFormName) - offsetof(DEVMODEA,dmFields));
  863. RtlCopyMemory(&pdmw->dmFields,
  864. &pdma->dmFields,
  865. cj);
  866. //
  867. // Is there a dmFormName field present in the pdma buffer? If not, bail out.
  868. // Otherwise, convert to Unicode.
  869. //
  870. if (pdma->dmSize >= (offsetof(DEVMODEA,dmFormName)+32))
  871. {
  872. vToUnicodeN(pdmw->dmFormName,
  873. CCHFORMNAME,
  874. pdma->dmFormName,
  875. CCHFORMNAME);
  876. pdmw->dmSize += CCHFORMNAME;
  877. //
  878. // Lets adjust the size of the DEVMODE in case the DEVMODE passed in
  879. // is from a future, larger version of the DEVMODE.
  880. //
  881. pdmw->dmSize = min(pdmw->dmSize, sizeof(DEVMODEW));
  882. //
  883. // Copy data from dmBitsPerPel to the end of the input buffer
  884. // (as specified by dmSize).
  885. //
  886. RtlCopyMemory(&pdmw->dmLogPixels,
  887. &pdma->dmLogPixels,
  888. MIN(pdma->dmSize - offsetof(DEVMODEA,dmLogPixels),
  889. pdmw->dmSize - offsetof(DEVMODEW,dmLogPixels)) );
  890. //
  891. // Copy any driver specific data indicated by the dmDriverExtra field.
  892. //
  893. RtlCopyMemory((PBYTE) pdmw + pdmw->dmSize,
  894. (PBYTE) pdma + pdma->dmSize,
  895. pdma->dmDriverExtra );
  896. }
  897. }
  898. return pdmw;
  899. }
  900. /******************************Public*Routine******************************\
  901. * CreateCompatibleDC *
  902. * *
  903. * Client side stub. Allocates a client side LDC as well. *
  904. * *
  905. * Note that it calls the server only after all client side stuff has *
  906. * succeeded, we don't want to ask the server to clean up. *
  907. * *
  908. * History: *
  909. * Wed 24-Jul-1991 15:38:41 -by- Wendy Wu [wendywu] *
  910. * Should allow hdc to be NULL. *
  911. * *
  912. * Mon 03-Jun-1991 23:13:28 -by- Charles Whitmer [chuckwh] *
  913. * Wrote it. *
  914. \**************************************************************************/
  915. HDC WINAPI CreateCompatibleDC(HDC hdc)
  916. {
  917. HDC hdcNew = NULL;
  918. FIXUP_HANDLEZ(hdc);
  919. hdcNew = NtGdiCreateCompatibleDC(hdc);
  920. // [Windows 98 compatibility]
  921. //
  922. // if source DC has some ICM information, compatible DC should
  923. // inherit those information.
  924. //
  925. // Is this what Memphis does, but Win95 does not.
  926. //
  927. if (hdc && hdcNew)
  928. {
  929. PDC_ATTR pdca;
  930. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  931. if (pdca && BEXIST_ICMINFO(pdca))
  932. {
  933. IcmEnableForCompatibleDC(hdcNew,hdc,pdca);
  934. }
  935. }
  936. return(hdcNew);
  937. }
  938. /******************************Public*Routine******************************\
  939. * DeleteDC *
  940. * *
  941. * Client side stub. Deletes the client side LDC as well. *
  942. * *
  943. * Note that we give the server a chance to fail the call before destroying *
  944. * our client side data. *
  945. * *
  946. * History: *
  947. * Sat 01-Jun-1991 16:16:24 -by- Charles Whitmer [chuckwh] *
  948. * Wrote it. *
  949. \**************************************************************************/
  950. BOOL WINAPI DeleteDC(HDC hdc)
  951. {
  952. FIXUP_HANDLE(hdc);
  953. return(InternalDeleteDC(hdc,LO_DC_TYPE));
  954. }
  955. BOOL InternalDeleteDC(HDC hdc,ULONG iType)
  956. {
  957. ULONG bRet = FALSE;
  958. PLDC pldc = NULL;
  959. BOOL unloadUMPD = FALSE;
  960. PDC_ATTR pDcAttr;
  961. HANDLE hSpooler = 0;
  962. if (IS_ALTDC_TYPE(hdc))
  963. {
  964. DC_PLDC(hdc,pldc,bRet);
  965. // In case a document is still open.
  966. if (pldc->fl & LDC_DOC_STARTED)
  967. AbortDoc(hdc);
  968. // if this was a metafiled print job, AbortDoc should have converted back
  969. ASSERTGDI(!(pldc->fl & LDC_META_PRINT), "InternalDeleteDC - LDC_META_PRINT\n");
  970. // if we have an open spooler handle
  971. if (pldc->hSpooler)
  972. {
  973. // now call the drivers UI portion
  974. DocumentEventEx(pldc->pUMPD,
  975. pldc->hSpooler,
  976. hdc,
  977. DOCUMENTEVENT_DELETEDC,
  978. 0,
  979. NULL,
  980. 0,
  981. NULL);
  982. //
  983. // Remember to unload user-mode printer driver module later
  984. //
  985. unloadUMPD = (pldc->pUMPD != NULL);
  986. ASSERTGDI(ghSpooler != NULL,"Trying to close printer that was never opened\n");
  987. //
  988. // remember hspooler, for not printer dcs, hspooler may not be initialized
  989. //
  990. hSpooler = pldc->hSpooler;
  991. pldc->hSpooler = 0;
  992. }
  993. // delete the port name if it was created
  994. if (pldc->pwszPort != NULL)
  995. {
  996. LOCALFREE(pldc->pwszPort);
  997. pldc->pwszPort = NULL;
  998. }
  999. // delete UFI hash tables if they exist
  1000. vFreeUFIHashTable( pldc->ppUFIHash, 0 );
  1001. vFreeUFIHashTable( pldc->ppDVUFIHash, 0 );
  1002. vFreeUFIHashTable( pldc->ppSubUFIHash, FL_UFI_SUBSET);
  1003. if (pldc->ppUFIHash)
  1004. {
  1005. // client side situation: all three ppXXX tables allocated
  1006. LOCALFREE(pldc->ppUFIHash);
  1007. }
  1008. else
  1009. {
  1010. // server side situation: possibly only ppSubUFIHash tables allocated
  1011. ASSERTGDI(!pldc->ppDVUFIHash, "server side pldc->ppDVUFIHash not null\n");
  1012. if (pldc->ppSubUFIHash)
  1013. LOCALFREE(pldc->ppSubUFIHash);
  1014. }
  1015. }
  1016. else
  1017. {
  1018. pldc = GET_PLDC(hdc);
  1019. }
  1020. // save the old brush, so we can DEC its counter later
  1021. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  1022. if (pDcAttr)
  1023. {
  1024. if (ghICM || BEXIST_ICMINFO(pDcAttr))
  1025. {
  1026. //
  1027. // Delete ICM stuff in this DC. (should be delete this BEFORE hdc is gone)
  1028. //
  1029. IcmDeleteLocalDC(hdc,pDcAttr,NULL);
  1030. }
  1031. bRet = NtGdiDeleteObjectApp(hdc);
  1032. if (hSpooler)
  1033. {
  1034. (*fpClosePrinter)(hSpooler);
  1035. }
  1036. }
  1037. // delete the client piece only if the server is successfully deleted.
  1038. // othewise it will be orphaned.
  1039. if (bRet && pldc)
  1040. {
  1041. if (unloadUMPD)
  1042. {
  1043. UnloadUserModePrinterDriver(pldc->pUMPD, TRUE, hSpooler);
  1044. pldc->pUMPD = NULL;
  1045. }
  1046. bRet = bDeleteLDC(pldc);
  1047. ASSERTGDI(bRet,"InteranlDeleteDC - couldn't delete LDC\n");
  1048. }
  1049. return(bRet);
  1050. }
  1051. /******************************Public*Routine******************************\
  1052. * GdiReleaseDC
  1053. *
  1054. * Free user mode ICM resources saved in DC
  1055. *
  1056. * Arguments:
  1057. *
  1058. * hdc
  1059. *
  1060. * Return Value:
  1061. *
  1062. * status
  1063. *
  1064. * History:
  1065. *
  1066. * Rewrite it for ICM.
  1067. * 2.Feb.1997 Hideyuki Nagase [hideyukn]
  1068. * Write it:
  1069. * 10/10/1996 Mark Enstrom [marke]
  1070. *
  1071. \**************************************************************************/
  1072. BOOL
  1073. GdiReleaseDC(
  1074. HDC hdc
  1075. )
  1076. {
  1077. PLDC pldc;
  1078. PDC_ATTR pDcAttr;
  1079. BOOL bRet = TRUE;
  1080. pldc = GET_PLDC(hdc);
  1081. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  1082. if (pDcAttr && (ghICM || BEXIST_ICMINFO(pDcAttr)))
  1083. {
  1084. //
  1085. // Delete ICM stuff in this DC.
  1086. //
  1087. IcmDeleteLocalDC(hdc,pDcAttr,NULL);
  1088. }
  1089. if (pldc)
  1090. {
  1091. //
  1092. // PLDC has been allocated. free it.
  1093. //
  1094. // Put null-PLDC into DC_ATTR.
  1095. //
  1096. vSetPldc(hdc,NULL);
  1097. //
  1098. // And, then delete PLDC.
  1099. //
  1100. bRet = bDeleteLDC(pldc);
  1101. }
  1102. return(bRet);
  1103. }
  1104. /******************************Public*Routine******************************\
  1105. * SaveDC *
  1106. * *
  1107. * Client side stub. Saves the LDC on the client side as well. *
  1108. * *
  1109. * History: *
  1110. * Sat 01-Jun-1991 16:17:43 -by- Charles Whitmer [chuckwh] *
  1111. * Wrote it. *
  1112. \**************************************************************************/
  1113. int WINAPI SaveDC(HDC hdc)
  1114. {
  1115. int iRet = 0;
  1116. PDC_ATTR pDcAttr;
  1117. FIXUP_HANDLE(hdc);
  1118. if (IS_ALTDC_TYPE(hdc))
  1119. {
  1120. PLDC pldc;
  1121. if (IS_METADC16_TYPE(hdc))
  1122. return (MF16_RecordParms1(hdc, META_SAVEDC));
  1123. DC_PLDC(hdc,pldc,iRet);
  1124. if (pldc->iType == LO_METADC)
  1125. {
  1126. if (!MF_Record(hdc,EMR_SAVEDC))
  1127. return(iRet);
  1128. }
  1129. }
  1130. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  1131. if (pDcAttr)
  1132. {
  1133. PGDI_ICMINFO pIcmInfo = GET_ICMINFO(pDcAttr);
  1134. //
  1135. // If DC doesn't have ICMINFO, just call kernel.
  1136. // If DC has ICMINFO, save ICMINFO first in client side, then call kernel.
  1137. //
  1138. if ((pIcmInfo == NULL) || (IcmSaveDC(hdc,pDcAttr,pIcmInfo)))
  1139. {
  1140. //
  1141. // Call kernel to save DC.
  1142. //
  1143. iRet = NtGdiSaveDC(hdc);
  1144. if ((iRet == 0) && (pIcmInfo))
  1145. {
  1146. //
  1147. // if fail, restore client too.
  1148. //
  1149. IcmRestoreDC(pDcAttr,-1,pIcmInfo);
  1150. }
  1151. }
  1152. }
  1153. return(iRet);
  1154. }
  1155. /******************************Public*Routine******************************\
  1156. * RestoreDC *
  1157. * *
  1158. * Client side stub. Restores the client side LDC as well. *
  1159. * *
  1160. * History: *
  1161. * Sat 01-Jun-1991 16:18:50 -by- Charles Whitmer [chuckwh] *
  1162. * Wrote it. (We could make this batchable some day.) *
  1163. \**************************************************************************/
  1164. BOOL WINAPI RestoreDC(HDC hdc,int iLevel)
  1165. {
  1166. BOOL bRet = FALSE;
  1167. PDC_ATTR pDcAttr;
  1168. FIXUP_HANDLE(hdc);
  1169. // Metafile the call.
  1170. if (IS_ALTDC_TYPE(hdc))
  1171. {
  1172. PLDC pldc;
  1173. if (IS_METADC16_TYPE(hdc))
  1174. return (MF16_RecordParms2(hdc, iLevel, META_RESTOREDC));
  1175. DC_PLDC(hdc,pldc,bRet);
  1176. if (pldc->iType == LO_METADC)
  1177. {
  1178. if (!MF_RestoreDC(hdc,iLevel))
  1179. return(bRet);
  1180. // zero out UFI since it will no longer be valid
  1181. UFI_CLEAR_ID(&(pldc->ufi));
  1182. }
  1183. }
  1184. // save the old brush, so we can DEC it's count later
  1185. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  1186. if (pDcAttr)
  1187. {
  1188. //
  1189. // Keep current ICMINFO, before restore it
  1190. //
  1191. PGDI_ICMINFO pIcmInfoOld = GET_ICMINFO(pDcAttr);
  1192. if (pIcmInfoOld)
  1193. {
  1194. //
  1195. // And mark the ICMINFO unreuseable since under restoring DC.
  1196. //
  1197. IcmMarkInUseIcmInfo(pIcmInfoOld,TRUE);
  1198. }
  1199. //
  1200. // Call kernel to do retore DC.
  1201. //
  1202. bRet = NtGdiRestoreDC(hdc,iLevel);
  1203. if (bRet)
  1204. {
  1205. PGDI_ICMINFO pIcmInfo = GET_ICMINFO(pDcAttr);
  1206. if (pIcmInfoOld && (pIcmInfo == NULL))
  1207. {
  1208. //
  1209. // Delete ICM stuffs associated the DC before Restore.
  1210. // beccause Restored DC does not have any ICMINFO.
  1211. //
  1212. // - This will delete pIcmInfoOld.
  1213. //
  1214. IcmDeleteLocalDC(hdc,pDcAttr,pIcmInfoOld);
  1215. pIcmInfoOld = NULL;
  1216. }
  1217. else if (pIcmInfoOld == pIcmInfo)
  1218. {
  1219. //
  1220. // Restore DC in client side.
  1221. //
  1222. IcmRestoreDC(pDcAttr,iLevel,pIcmInfo);
  1223. }
  1224. }
  1225. if (pIcmInfoOld)
  1226. {
  1227. //
  1228. // Unmark unreusable flags.
  1229. //
  1230. IcmMarkInUseIcmInfo(pIcmInfoOld,FALSE);
  1231. }
  1232. CLEAR_CACHED_TEXT(pDcAttr);
  1233. }
  1234. return (bRet);
  1235. }
  1236. /******************************Public*Routine******************************\
  1237. * ResetDCWInternal
  1238. *
  1239. * This internal version version of ResetDC implments the functionality of
  1240. * ResetDCW, but, through the addition of a third parameter, pbBanding, handles
  1241. * ResetDC for the Printing metafile playback code. When pbBanding is non-NULL
  1242. * ResetDCWInternal is being called by GdiPlayEMFSpoolfile. In this case
  1243. * the only thing that needs to be done is to imform the the caller whether or
  1244. * not the new surface is a banding surface.
  1245. *
  1246. *
  1247. * History:
  1248. * 13-Mar-1995 Gerrit van Wingerden [gerritv]
  1249. * Wrote it.
  1250. \**************************************************************************/
  1251. HDC WINAPI ResetDCWInternal(HDC hdc, CONST DEVMODEW *pdm, BOOL *pbBanding)
  1252. {
  1253. HDC hdcRet = NULL;
  1254. PLDC pldc = NULL;
  1255. PDEVMODEW pdmAlt = NULL;
  1256. KERNEL_PUMDHPDEV pUMdhpdev = NULL;
  1257. BOOL bDocEvent = FALSE;
  1258. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  1259. {
  1260. PDC_ATTR pdcattr;
  1261. BOOL bBanding;
  1262. PUMPD pUMPD;
  1263. PGDI_ICMINFO pIcmInfoOld = NULL;
  1264. int iEventRet;
  1265. DC_PLDC(hdc,pldc,(HDC) 0);
  1266. PSHARED_GET_VALIDATE(pdcattr,hdc,DC_TYPE);
  1267. // Do nothing if we are in the middle of a page.
  1268. if (pldc->fl & LDC_PAGE_STARTED)
  1269. return((HDC)0);
  1270. // see if the driver is intercepting document events
  1271. if (pldc->hSpooler)
  1272. {
  1273. iEventRet = DocumentEventEx(pldc->pUMPD,
  1274. pldc->hSpooler,
  1275. hdc,
  1276. DOCUMENTEVENT_RESETDCPRE,
  1277. sizeof(pdm),
  1278. (PVOID)&pdm,
  1279. sizeof(pdmAlt),
  1280. (PVOID)&pdmAlt);
  1281. if (iEventRet == DOCUMENTEVENT_FAILURE)
  1282. {
  1283. return((HDC)0);
  1284. }
  1285. bDocEvent = TRUE;
  1286. if (pdmAlt)
  1287. pdm = pdmAlt;
  1288. }
  1289. pUMPD = pldc->pUMPD;
  1290. if (pdcattr)
  1291. {
  1292. // Keep current ICMINFO, before reset it.
  1293. pIcmInfoOld = GET_ICMINFO(pdcattr);
  1294. if (pIcmInfoOld)
  1295. {
  1296. // And mark the ICMINFO unreuseable since under restoring DC.
  1297. IcmMarkInUseIcmInfo(pIcmInfoOld,TRUE);
  1298. }
  1299. }
  1300. if (NtGdiResetDC(hdc,(PDEVMODEW)pdm,&bBanding,
  1301. (pUMPD == NULL)? NULL : pUMPD->pDriverInfo2, &pUMdhpdev))
  1302. {
  1303. PDC_ATTR pdca;
  1304. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  1305. // make sure we update the pldc in the dcattr before continuing
  1306. vSetPldc(hdc,pldc);
  1307. #if 0
  1308. // EngQueryEMFInfo junk
  1309. if (pUMdhpdev)
  1310. {
  1311. pUMdhpdev->hdc = hdc;
  1312. }
  1313. #endif
  1314. pldc->pUMdhpdev = pUMdhpdev;
  1315. // clear cached DEVCAPS
  1316. pldc->fl &= ~LDC_CACHED_DEVCAPS;
  1317. // clear cached TM
  1318. if (pdca)
  1319. {
  1320. CLEAR_CACHED_TEXT(pdca);
  1321. }
  1322. // update the devmode we store in the DC
  1323. if (pldc->pDevMode)
  1324. {
  1325. LOCALFREE(pldc->pDevMode);
  1326. pldc->pDevMode = NULL;
  1327. }
  1328. if (pdm != (DEVMODEW*) NULL)
  1329. {
  1330. ULONG cjDevMode = pdm->dmSize + pdm->dmDriverExtra;
  1331. pldc->pDevMode = (DEVMODEW*) LOCALALLOC(cjDevMode);
  1332. if (pldc->pDevMode == NULL)
  1333. {
  1334. WARNING("MFP_ResetDCW unable to allocate memory\n");
  1335. goto ERROREXIT;
  1336. }
  1337. // Validate DEVMMODE, then copy to buffer.
  1338. if ((pdm->dmSize >= offsetof(DEVMODEW,dmDuplex)) &&
  1339. (pdm->dmFields & DM_COLOR) &&
  1340. (pdm->dmColor == DMCOLOR_MONOCHROME))
  1341. {
  1342. // if devmode says, this is monochrome mode, we don't need to
  1343. // validate devmode since this validation is for ICM which
  1344. // only needs for color case. Just copy whatever apps gives us.
  1345. RtlCopyMemory( (PBYTE) pldc->pDevMode, (PBYTE) pdm, cjDevMode );
  1346. }
  1347. else if ((*fpDocumentPropertiesW)
  1348. (NULL,pldc->hSpooler,
  1349. (LPWSTR) pdm->dmDeviceName,
  1350. pldc->pDevMode, // output devmode
  1351. (PDEVMODEW) pdm, // input devmode
  1352. DM_IN_BUFFER |
  1353. DM_OUT_BUFFER) != IDOK)
  1354. {
  1355. // if error, just copy original
  1356. RtlCopyMemory( (PBYTE) pldc->pDevMode, (PBYTE) pdm, cjDevMode );
  1357. }
  1358. }
  1359. // make sure we update the pvICM in the dcattr before continuing
  1360. if (pdca)
  1361. {
  1362. // This old ICM info will be deleted when we re-initialize ICM
  1363. // status based on new DEVMODE.
  1364. pdca->pvICM = pIcmInfoOld;
  1365. pIcmInfoOld = NULL;
  1366. // Re-initialize ICM stuff with new DEVMODE
  1367. IcmInitLocalDC(hdc,pldc->hSpooler,pdm,TRUE);
  1368. }
  1369. // got to tell the spooler things have changed
  1370. if (pldc->hSpooler)
  1371. {
  1372. PRINTER_DEFAULTSW prnDefaults;
  1373. prnDefaults.pDatatype = NULL;
  1374. prnDefaults.pDevMode = (PDEVMODEW)pdm;
  1375. prnDefaults.DesiredAccess = PRINTER_ACCESS_USE;
  1376. ResetPrinterWEx(pldc, &prnDefaults);
  1377. }
  1378. // now deal with the specific mode
  1379. if( ( pldc->fl & LDC_META_PRINT ) &&
  1380. !( pldc->fl & LDC_BANDING ) )
  1381. {
  1382. if( !MFP_ResetDCW( hdc, (DEVMODEW*) pdm ) )
  1383. {
  1384. goto ERROREXIT;
  1385. }
  1386. }
  1387. else if( pbBanding == NULL )
  1388. {
  1389. if( !MFP_ResetBanding( hdc, bBanding ) )
  1390. {
  1391. goto ERROREXIT;
  1392. }
  1393. }
  1394. if (pbBanding)
  1395. {
  1396. *pbBanding = bBanding;
  1397. }
  1398. // need to make sure it is a direct DC
  1399. pldc->fl &= ~LDC_INFO;
  1400. hdcRet = hdc;
  1401. }
  1402. if (pIcmInfoOld)
  1403. {
  1404. IcmMarkInUseIcmInfo(pIcmInfoOld,FALSE);
  1405. }
  1406. }
  1407. ERROREXIT:
  1408. // see if the driver is intercepting document events
  1409. if (bDocEvent)
  1410. {
  1411. DocumentEventEx(pldc->pUMPD,
  1412. pldc->hSpooler,
  1413. hdc,
  1414. DOCUMENTEVENT_RESETDCPOST,
  1415. sizeof(pdmAlt),
  1416. (PVOID)&pdmAlt,
  1417. 0,
  1418. NULL);
  1419. }
  1420. return(hdcRet);
  1421. }
  1422. /******************************Public*Routine******************************\
  1423. * ResetDCW
  1424. *
  1425. * Client side stub. Resets the client side LDC as well.
  1426. *
  1427. * History:
  1428. * 31-Dec-1992 -by- Donald Sidoroff [donalds]
  1429. * Wrote it.
  1430. \**************************************************************************/
  1431. HDC WINAPI ResetDCW(HDC hdc, CONST DEVMODEW *pdm)
  1432. {
  1433. FIXUP_HANDLE(hdc);
  1434. return(ResetDCWInternal( hdc, pdm, NULL ) );
  1435. }
  1436. /******************************Public*Routine******************************\
  1437. * ResetDCA
  1438. *
  1439. * Client side stub. Resets the client side LDC as well.
  1440. *
  1441. * History:
  1442. * 31-Dec-1992 -by- Donald Sidoroff [donalds]
  1443. * Wrote it.
  1444. \**************************************************************************/
  1445. HDC WINAPI ResetDCA(HDC hdc, CONST DEVMODEA *pdm)
  1446. {
  1447. DEVMODEW *pdmw = NULL;
  1448. HDC hdcRet = 0;
  1449. FIXUP_HANDLE(hdc);
  1450. // convert to unicode
  1451. if ((pdm != NULL) && (pdm->dmDeviceName[0] != 0))
  1452. {
  1453. pdmw = GdiConvertToDevmodeW((LPDEVMODEA) pdm);
  1454. if (pdmw == NULL)
  1455. {
  1456. goto MSGERROR;
  1457. }
  1458. }
  1459. hdcRet = ResetDCWInternal(hdc,pdmw,NULL);
  1460. MSGERROR:
  1461. // Clean up the conversion buffer
  1462. if (pdmw != NULL)
  1463. LOCALFREE(pdmw);
  1464. return (hdcRet);
  1465. }
  1466. /******************************Public*Routine******************************\
  1467. * CreateBrush *
  1468. * *
  1469. * A single routine which creates any brush. Any extra data needed is *
  1470. * assumed to be at pv. The size of the data must be cj. The data is *
  1471. * appended to the LOGBRUSH. *
  1472. * *
  1473. * History: *
  1474. * Tue 04-Jun-1991 00:03:24 -by- Charles Whitmer [chuckwh] *
  1475. * Wrote it. *
  1476. \**************************************************************************/
  1477. HBRUSH CreateBrush
  1478. (
  1479. ULONG lbStyle,
  1480. ULONG lbColor,
  1481. ULONG_PTR lbHatch,
  1482. ULONG_PTR lbSaveHatch,
  1483. PVOID pv
  1484. )
  1485. {
  1486. HBRUSH hbrush = NULL;
  1487. if (lbStyle == BS_SOLID)
  1488. {
  1489. //
  1490. // look for a cached brush on the PEB
  1491. //
  1492. HBRUSH hbr = (HBRUSH)hGetPEBHandle(BrushHandle,lbColor);
  1493. if (hbr == NULL)
  1494. {
  1495. hbr = NtGdiCreateSolidBrush(lbColor, 0);
  1496. }
  1497. return(hbr);
  1498. }
  1499. //
  1500. // call into kernel to create other styles of brush
  1501. //
  1502. switch(lbStyle)
  1503. {
  1504. case BS_HOLLOW:
  1505. return(GetStockObject(NULL_BRUSH));
  1506. case BS_HATCHED:
  1507. //
  1508. // lbHatch is overloaded, actually is HS style
  1509. // we are safe to truncate it here
  1510. //
  1511. return (NtGdiCreateHatchBrushInternal
  1512. ((ULONG)(lbHatch),
  1513. lbColor,
  1514. FALSE));
  1515. case BS_PATTERN:
  1516. return (NtGdiCreatePatternBrushInternal((HBITMAP)lbHatch,FALSE,FALSE));
  1517. case BS_PATTERN8X8:
  1518. return (NtGdiCreatePatternBrushInternal((HBITMAP)lbHatch,FALSE,TRUE));
  1519. case BS_DIBPATTERN:
  1520. case BS_DIBPATTERNPT:
  1521. case BS_DIBPATTERN8X8:
  1522. {
  1523. INT cj;
  1524. HBRUSH hbr;
  1525. PVOID pbmiDIB;
  1526. pbmiDIB = (PVOID)pbmiConvertInfo((BITMAPINFO *) pv,lbColor, &cj, TRUE);
  1527. if (pbmiDIB)
  1528. {
  1529. hbr = NtGdiCreateDIBBrush(
  1530. (PVOID)pbmiDIB,
  1531. lbColor,
  1532. cj,
  1533. (lbStyle == BS_DIBPATTERN8X8),
  1534. FALSE,
  1535. (PVOID)pv);
  1536. if (pbmiDIB != pv)
  1537. {
  1538. LOCALFREE (pbmiDIB);
  1539. }
  1540. }
  1541. else
  1542. {
  1543. hbr = 0;
  1544. }
  1545. return (hbr);
  1546. }
  1547. default:
  1548. WARNING("GreCreateBrushIndirect failed - invalid type\n");
  1549. return((HBRUSH)0);
  1550. }
  1551. }
  1552. /******************************Public*Routine******************************\
  1553. * CreateHatchBrush *
  1554. * *
  1555. * Client side stub. Maps to the single brush creation routine. *
  1556. * *
  1557. * History:
  1558. * Mon 03-Jun-1991 23:42:07 -by- Charles Whitmer [chuckwh] *
  1559. * Wrote it. *
  1560. \**************************************************************************/
  1561. HBRUSH WINAPI CreateHatchBrush(int iHatch,COLORREF color)
  1562. {
  1563. return(CreateBrush(BS_HATCHED,(ULONG) color,iHatch,iHatch,NULL));
  1564. }
  1565. /******************************Public*Routine******************************\
  1566. * CreatePatternBrush *
  1567. * *
  1568. * Client side stub. Maps to the single brush creation routine. *
  1569. * *
  1570. * History: *
  1571. * Mon 03-Jun-1991 23:42:07 -by- Charles Whitmer [chuckwh] *
  1572. * Wrote it. *
  1573. \**************************************************************************/
  1574. HBRUSH WINAPI CreatePatternBrush(HBITMAP hbm_)
  1575. {
  1576. FIXUP_HANDLE (hbm_);
  1577. return(CreateBrush(BS_PATTERN,0,(ULONG_PTR)hbm_,(ULONG_PTR)hbm_,NULL));
  1578. }
  1579. /******************************Public*Routine******************************\
  1580. * CreateSolidBrush *
  1581. * *
  1582. * Client side stub. Maps to the single brush creation routine. *
  1583. * *
  1584. * History: *
  1585. * Mon 03-Jun-1991 23:42:07 -by- Charles Whitmer [chuckwh] *
  1586. * Wrote it. *
  1587. \**************************************************************************/
  1588. HBRUSH WINAPI CreateSolidBrush(COLORREF color)
  1589. {
  1590. return(CreateBrush(BS_SOLID,(ULONG) color,0,0,NULL));
  1591. }
  1592. /******************************Public*Routine******************************\
  1593. * CreateBrushIndirect *
  1594. * *
  1595. * Client side stub. Maps to the simplest brush creation routine. *
  1596. * *
  1597. * History: *
  1598. * Tue 04-Jun-1991 00:40:27 -by- Charles Whitmer [chuckwh] *
  1599. * Wrote it. *
  1600. \**************************************************************************/
  1601. HBRUSH WINAPI CreateBrushIndirect(CONST LOGBRUSH * plbrush)
  1602. {
  1603. switch (plbrush->lbStyle)
  1604. {
  1605. case BS_SOLID:
  1606. case BS_HOLLOW:
  1607. case BS_HATCHED:
  1608. return(CreateBrush(plbrush->lbStyle,
  1609. plbrush->lbColor,
  1610. plbrush->lbHatch,
  1611. plbrush->lbHatch,
  1612. NULL));
  1613. case BS_PATTERN:
  1614. case BS_PATTERN8X8:
  1615. {
  1616. return(CreateBrush(
  1617. plbrush->lbStyle,
  1618. 0,
  1619. plbrush->lbHatch,
  1620. plbrush->lbHatch,
  1621. NULL));
  1622. }
  1623. case BS_DIBPATTERNPT:
  1624. case BS_DIBPATTERN8X8:
  1625. {
  1626. BITMAPINFOHEADER *pbmi = (BITMAPINFOHEADER *) plbrush->lbHatch;
  1627. return (CreateBrush(plbrush->lbStyle,
  1628. plbrush->lbColor,
  1629. 0,
  1630. plbrush->lbHatch,
  1631. pbmi));
  1632. }
  1633. case BS_DIBPATTERN:
  1634. {
  1635. BITMAPINFOHEADER *pbmi;
  1636. HBRUSH hbrush;
  1637. pbmi = (BITMAPINFOHEADER *) GlobalLock((HANDLE) plbrush->lbHatch);
  1638. if (pbmi == (BITMAPINFOHEADER *) NULL)
  1639. return((HBRUSH) 0);
  1640. hbrush =
  1641. CreateBrush
  1642. (
  1643. plbrush->lbStyle,
  1644. plbrush->lbColor,
  1645. 0,
  1646. plbrush->lbHatch,
  1647. pbmi
  1648. );
  1649. GlobalUnlock ((HANDLE)plbrush->lbHatch);
  1650. return (hbrush);
  1651. }
  1652. default:
  1653. return((HBRUSH) 0);
  1654. }
  1655. }
  1656. /******************************Public*Routine******************************\
  1657. * CreateDIBPatternBrush *
  1658. * *
  1659. * Client side stub. Maps to the single brush creation routine. *
  1660. * *
  1661. * History: *
  1662. * Mon 03-Jun-1991 23:42:07 -by- Charles Whitmer [chuckwh] *
  1663. * Wrote it. *
  1664. \**************************************************************************/
  1665. HBRUSH WINAPI CreateDIBPatternBrush(HGLOBAL h,UINT iUsage)
  1666. {
  1667. BITMAPINFOHEADER *pbmi;
  1668. HBRUSH hbrush;
  1669. pbmi = (BITMAPINFOHEADER *) GlobalLock(h);
  1670. if (pbmi == (BITMAPINFOHEADER *) NULL)
  1671. return((HBRUSH) 0);
  1672. hbrush =
  1673. CreateBrush
  1674. (
  1675. BS_DIBPATTERN,
  1676. iUsage,
  1677. 0,
  1678. (ULONG_PTR) h,
  1679. pbmi
  1680. );
  1681. GlobalUnlock(h);
  1682. return(hbrush);
  1683. }
  1684. /******************************Public*Routine******************************\
  1685. * CreateDIBPatternBrushPt *
  1686. * *
  1687. * Client side stub. Maps to the single brush creation routine. *
  1688. * *
  1689. * History: *
  1690. * Mon 03-Jun-1991 23:42:07 -by- Charles Whitmer [chuckwh] *
  1691. * Wrote it. *
  1692. \**************************************************************************/
  1693. HBRUSH WINAPI CreateDIBPatternBrushPt(CONST VOID *pbmi,UINT iUsage)
  1694. {
  1695. if (pbmi == (LPVOID) NULL)
  1696. return((HBRUSH) 0);
  1697. return
  1698. CreateBrush
  1699. (
  1700. BS_DIBPATTERNPT,
  1701. iUsage,
  1702. 0,
  1703. (ULONG_PTR)pbmi,
  1704. (BITMAPINFOHEADER *)pbmi
  1705. );
  1706. }
  1707. /******************************Public*Routine******************************\
  1708. * CreatePen *
  1709. * *
  1710. * Stub to get the server to create a standard pen. *
  1711. * *
  1712. * History: *
  1713. * Tue 04-Jun-1991 16:20:58 -by- Charles Whitmer [chuckwh] *
  1714. * Wrote it. *
  1715. \**************************************************************************/
  1716. HPEN WINAPI CreatePen(
  1717. int iStyle,
  1718. int cWidth,
  1719. COLORREF color
  1720. )
  1721. {
  1722. HPEN hpen;
  1723. switch(iStyle)
  1724. {
  1725. case PS_NULL:
  1726. return(GetStockObject(NULL_PEN));
  1727. case PS_SOLID:
  1728. case PS_DASH:
  1729. case PS_DOT:
  1730. case PS_DASHDOT:
  1731. case PS_DASHDOTDOT:
  1732. case PS_INSIDEFRAME:
  1733. break;
  1734. default:
  1735. // Bug 195478: objects created with illegal styles should be of style PS_SOLID to
  1736. // maintain Memphis compatibility.
  1737. iStyle = PS_SOLID;
  1738. break;
  1739. }
  1740. // try to get local cached pen
  1741. if ((cWidth == 0) && (iStyle == PS_SOLID))
  1742. {
  1743. hpen = (HPEN)hGetPEBHandle(PenHandle,0);
  1744. if (hpen)
  1745. {
  1746. PBRUSHATTR pBrushattr;
  1747. PSHARED_GET_VALIDATE(pBrushattr,hpen,BRUSH_TYPE);
  1748. //
  1749. // setup the fields
  1750. //
  1751. if (pBrushattr)
  1752. {
  1753. ASSERTGDI (!(pBrushattr->AttrFlags & ATTR_TO_BE_DELETED),"createbrush : how come del flag is on?\n");
  1754. //
  1755. // clear cahced flag, set new style and color
  1756. //
  1757. if (pBrushattr->lbColor != color)
  1758. {
  1759. pBrushattr->AttrFlags |= ATTR_NEW_COLOR;
  1760. pBrushattr->lbColor = color;
  1761. }
  1762. return(hpen);
  1763. }
  1764. else
  1765. {
  1766. WARNING ("pBrushattr == NULL, bad handle on TEB/PEB! \n");
  1767. DeleteObject(hpen);
  1768. }
  1769. }
  1770. }
  1771. //
  1772. // validate
  1773. //
  1774. return(NtGdiCreatePen(iStyle,cWidth,color,(HBRUSH)NULL));
  1775. }
  1776. /******************************Public*Routine******************************\
  1777. * ExtCreatePen
  1778. *
  1779. * Client side stub. The style array is appended to the end of the
  1780. * EXTLOGPEN structure, and if the call requires a DIBitmap it is appended
  1781. * at the end of this.
  1782. *
  1783. * History:
  1784. * Wed 22-Jan-1992 -by- J. Andrew Goossen [andrewgo]
  1785. * Wrote it.
  1786. \**************************************************************************/
  1787. HPEN WINAPI ExtCreatePen
  1788. (
  1789. DWORD iPenStyle,
  1790. DWORD cWidth,
  1791. CONST LOGBRUSH *plbrush,
  1792. DWORD cStyle,
  1793. CONST DWORD *pstyle
  1794. )
  1795. {
  1796. HANDLE hRet;
  1797. ULONG cjStyle;
  1798. ULONG cjBitmap = 0;
  1799. ULONG_PTR lNewHatch;
  1800. BITMAPINFOHEADER* pbmi = (BITMAPINFOHEADER*) NULL;
  1801. UINT uiBrushStyle = plbrush->lbStyle;
  1802. PVOID pbmiDIB = NULL;
  1803. if ((iPenStyle & PS_STYLE_MASK) == PS_USERSTYLE)
  1804. {
  1805. if (pstyle == (LPDWORD) NULL)
  1806. {
  1807. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1808. return((HPEN) 0);
  1809. }
  1810. }
  1811. else
  1812. {
  1813. // Make sure style array is empty if PS_USERSTYLE not specified:
  1814. if (cStyle != 0 || pstyle != (LPDWORD) NULL)
  1815. {
  1816. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1817. return((HPEN) 0);
  1818. }
  1819. }
  1820. switch(uiBrushStyle)
  1821. {
  1822. case BS_SOLID:
  1823. case BS_HOLLOW:
  1824. case BS_HATCHED:
  1825. lNewHatch = plbrush->lbHatch;
  1826. break;
  1827. case BS_PATTERN:
  1828. lNewHatch = plbrush->lbHatch;
  1829. if (lNewHatch == 0)
  1830. return((HPEN) 0);
  1831. break;
  1832. case BS_DIBPATTERNPT:
  1833. pbmi = (BITMAPINFOHEADER *) plbrush->lbHatch;
  1834. pbmiDIB = (PVOID) pbmiConvertInfo ((BITMAPINFO *) pbmi, plbrush->lbColor, &cjBitmap, TRUE);
  1835. lNewHatch = (ULONG_PTR)pbmiDIB;
  1836. break;
  1837. case BS_DIBPATTERN:
  1838. // Convert BS_DIBPATTERN to a BS_DIBPATTERNPT call:
  1839. uiBrushStyle = BS_DIBPATTERNPT;
  1840. pbmi = (BITMAPINFOHEADER *) GlobalLock((HANDLE) plbrush->lbHatch);
  1841. if (pbmi == (BITMAPINFOHEADER *) NULL)
  1842. return((HPEN) 0);
  1843. pbmiDIB = (PVOID) pbmiConvertInfo ((BITMAPINFO *) pbmi, plbrush->lbColor, &cjBitmap, TRUE);
  1844. lNewHatch = (ULONG_PTR)pbmiDIB;
  1845. break;
  1846. }
  1847. // Ask the server to create the pen:
  1848. cjStyle = cStyle * sizeof(DWORD);
  1849. hRet = NtGdiExtCreatePen(
  1850. iPenStyle,
  1851. cWidth,
  1852. uiBrushStyle,
  1853. plbrush->lbColor,
  1854. plbrush->lbHatch,
  1855. lNewHatch,
  1856. cStyle,
  1857. (DWORD*)pstyle,
  1858. cjBitmap,
  1859. FALSE,
  1860. 0);
  1861. if (hRet)
  1862. {
  1863. ASSERTGDI(((LO_TYPE (hRet) == LO_PEN_TYPE) ||
  1864. (LO_TYPE (hRet) == LO_EXTPEN_TYPE)), "EXTCreatePen - type wrong\n");
  1865. }
  1866. if (plbrush->lbStyle == BS_DIBPATTERN)
  1867. GlobalUnlock((HANDLE) plbrush->lbHatch);
  1868. if (pbmiDIB && (pbmiDIB != (PVOID)pbmi))
  1869. LOCALFREE(pbmiDIB);
  1870. return((HPEN) hRet);
  1871. }
  1872. /******************************Public*Routine******************************\
  1873. * CreatePenIndirect *
  1874. * *
  1875. * Client side stub. Maps to the single pen creation routine. *
  1876. * *
  1877. * History: *
  1878. * Tue 04-Jun-1991 16:21:56 -by- Charles Whitmer [chuckwh] *
  1879. * Wrote it. *
  1880. \**************************************************************************/
  1881. HPEN WINAPI CreatePenIndirect(CONST LOGPEN *plpen)
  1882. {
  1883. return
  1884. CreatePen
  1885. (
  1886. plpen->lopnStyle,
  1887. plpen->lopnWidth.x,
  1888. plpen->lopnColor
  1889. );
  1890. }
  1891. /******************************Public*Routine******************************\
  1892. * CreateCompatibleBitmap *
  1893. * *
  1894. * Client side stub. *
  1895. * *
  1896. * History: *
  1897. * Tue 04-Jun-1991 16:35:51 -by- Charles Whitmer [chuckwh] *
  1898. * Wrote it. *
  1899. \**************************************************************************/
  1900. BOOL bDIBSectionSelected(
  1901. PDC_ATTR pdca
  1902. )
  1903. {
  1904. BOOL bRet = FALSE;
  1905. if ((pdca != NULL) && ((pdca->ulDirty_ & DC_DIBSECTION)))
  1906. {
  1907. bRet = TRUE;
  1908. }
  1909. return(bRet);
  1910. }
  1911. HBITMAP WINAPI CreateCompatibleBitmap
  1912. (
  1913. HDC hdc,
  1914. int cx,
  1915. int cy
  1916. )
  1917. {
  1918. HBITMAP hbm;
  1919. //
  1920. // validate hdc
  1921. //
  1922. PDC_ATTR pdca;
  1923. FIXUP_HANDLEZ(hdc);
  1924. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  1925. if (pdca)
  1926. {
  1927. ULONG ulRet;
  1928. DWORD bmi[(sizeof(DIBSECTION)+256*sizeof(RGBQUAD))/sizeof(DWORD)];
  1929. // check if it is an empty bitmap
  1930. if ((cx == 0) || (cy == 0))
  1931. {
  1932. return(GetStockObject(PRIV_STOCK_BITMAP));
  1933. }
  1934. if (bDIBSectionSelected(pdca))
  1935. {
  1936. if (GetObject((HBITMAP)GetDCObject(hdc, LO_BITMAP_TYPE), sizeof(DIBSECTION),
  1937. &bmi) != (int)sizeof(DIBSECTION))
  1938. {
  1939. WARNING("CreateCompatibleBitmap: GetObject failed\n");
  1940. return((HBITMAP) 0);
  1941. }
  1942. if (((DIBSECTION *)&bmi)->dsBm.bmBitsPixel <= 8)
  1943. GetDIBColorTable(hdc, 0, 256,
  1944. (RGBQUAD *)&((DIBSECTION *)&bmi)->dsBitfields[0]);
  1945. ((DIBSECTION *)&bmi)->dsBmih.biWidth = cx;
  1946. ((DIBSECTION *)&bmi)->dsBmih.biHeight = cy;
  1947. return(CreateDIBSection(hdc, (BITMAPINFO *)&((DIBSECTION *)&bmi)->dsBmih,
  1948. DIB_RGB_COLORS, NULL, 0, 0));
  1949. }
  1950. hbm = NtGdiCreateCompatibleBitmap(hdc,cx,cy);
  1951. #if TRACE_SURFACE_ALLOCS
  1952. {
  1953. PULONG pUserAlloc;
  1954. PSHARED_GET_VALIDATE(pUserAlloc, hbm, SURF_TYPE);
  1955. if (pUserAlloc != NULL)
  1956. {
  1957. pUserAlloc[1] = RtlWalkFrameChain((PVOID *)&pUserAlloc[2], pUserAlloc[0], 0);
  1958. }
  1959. }
  1960. #endif
  1961. return(hbm);
  1962. }
  1963. return(NULL);
  1964. }
  1965. /******************************Public*Routine******************************\
  1966. * CreateDiscardableBitmap *
  1967. * *
  1968. * Client side stub. *
  1969. * *
  1970. * History: *
  1971. * Tue 04-Jun-1991 16:35:51 -by- Charles Whitmer [chuckwh] *
  1972. * Wrote it. *
  1973. \**************************************************************************/
  1974. HBITMAP WINAPI CreateDiscardableBitmap
  1975. (
  1976. HDC hdc,
  1977. int cx,
  1978. int cy
  1979. )
  1980. {
  1981. return CreateCompatibleBitmap(hdc, cx, cy);
  1982. }
  1983. /******************************Public*Routine******************************\
  1984. * CreateEllipticRgn *
  1985. * *
  1986. * Client side stub. *
  1987. * *
  1988. * Tue 04-Jun-1991 16:58:01 -by- Charles Whitmer [chuckwh] *
  1989. * Wrote it. *
  1990. \**************************************************************************/
  1991. HRGN WINAPI CreateEllipticRgn(int x1,int y1,int x2,int y2)
  1992. {
  1993. return(NtGdiCreateEllipticRgn(x1,y1,x2,y2));
  1994. }
  1995. /******************************Public*Routine******************************\
  1996. * CreateEllipticRgnIndirect *
  1997. * *
  1998. * Client side stub. *
  1999. * *
  2000. * Tue 04-Jun-1991 16:58:01 -by- Charles Whitmer [chuckwh] *
  2001. * Wrote it. *
  2002. \**************************************************************************/
  2003. HRGN WINAPI CreateEllipticRgnIndirect(CONST RECT *prcl)
  2004. {
  2005. return
  2006. CreateEllipticRgn
  2007. (
  2008. prcl->left,
  2009. prcl->top,
  2010. prcl->right,
  2011. prcl->bottom
  2012. );
  2013. }
  2014. /******************************Public*Routine******************************\
  2015. * CreateRoundRectRgn *
  2016. * *
  2017. * Client side stub. *
  2018. * *
  2019. * Tue 04-Jun-1991 17:23:16 -by- Charles Whitmer [chuckwh] *
  2020. * Wrote it. *
  2021. \**************************************************************************/
  2022. HRGN WINAPI CreateRoundRectRgn
  2023. (
  2024. int x1,
  2025. int y1,
  2026. int x2,
  2027. int y2,
  2028. int cx,
  2029. int cy
  2030. )
  2031. {
  2032. return(NtGdiCreateRoundRectRgn(x1,y1,x2,y2,cx,cy));
  2033. }
  2034. /******************************Public*Routine******************************\
  2035. * CreatePalette *
  2036. * *
  2037. * Simple client side stub. *
  2038. * *
  2039. * Warning: *
  2040. * The pv field of a palette's lhe is used to determine if a palette *
  2041. * has been modified since it was last realized. SetPaletteEntries *
  2042. * and ResizePalette will increment this field after they have *
  2043. * modified the palette. It is only updated for metafiled palettes *
  2044. * *
  2045. * Tue 04-Jun-1991 20:43:39 -by- Charles Whitmer [chuckwh] *
  2046. * Wrote it. *
  2047. \**************************************************************************/
  2048. HPALETTE WINAPI CreatePalette(CONST LOGPALETTE *plpal)
  2049. {
  2050. return(NtGdiCreatePaletteInternal((LOGPALETTE*)plpal,plpal->palNumEntries));
  2051. }
  2052. /******************************Public*Routine******************************\
  2053. * CreateFontIndirectExW *
  2054. * *
  2055. * Client Side stub. *
  2056. * *
  2057. * History: *
  2058. * 7-12-94 -by- Lingyun Wang [lingyunw] removed LOCALFONT *
  2059. * Sun 10-Jan-1993 04:08:33 -by- Charles Whitmer [chuckwh] *
  2060. * Restructured for best tail merging. Added creation of the LOCALFONT. *
  2061. * *
  2062. * Thu 15-Aug-1991 08:40:26 by Kirk Olynyk [kirko] *
  2063. * Wrote it. *
  2064. \**************************************************************************/
  2065. HFONT WINAPI CreateFontIndirectExW(CONST ENUMLOGFONTEXDVW *pelfw)
  2066. {
  2067. LOCALFONT *plf;
  2068. FLONG fl = 0;
  2069. HFONT hfRet = (HFONT) 0;
  2070. if (pelfw->elfEnumLogfontEx.elfLogFont.lfEscapement | pelfw->elfEnumLogfontEx.elfLogFont.lfOrientation)
  2071. {
  2072. fl = LF_HARDWAY;
  2073. }
  2074. ENTERCRITICALSECTION(&semLocal);
  2075. plf = plfCreateLOCALFONT(fl);
  2076. LEAVECRITICALSECTION(&semLocal);
  2077. if( plf != NULL )
  2078. {
  2079. if (pelfw->elfDesignVector.dvNumAxes <= MM_MAX_NUMAXES)
  2080. {
  2081. ULONG cjElfw = offsetof(ENUMLOGFONTEXDVW,elfDesignVector) +
  2082. SIZEOFDV(pelfw->elfDesignVector.dvNumAxes) ;
  2083. hfRet = NtGdiHfontCreate((ENUMLOGFONTEXDVW *)pelfw, cjElfw, LF_TYPE_USER, 0, (PVOID) plf);
  2084. }
  2085. }
  2086. if( !hfRet && plf )
  2087. {
  2088. vDeleteLOCALFONT( plf );
  2089. }
  2090. return(hfRet);
  2091. }
  2092. /******************************Public*Routine******************************\
  2093. * CreateFontIndirect *
  2094. * *
  2095. * Client side stub. *
  2096. * *
  2097. * Fri 16-Aug-1991 12:35:17 by Kirk Olynyk [kirko] * *
  2098. * Now uses CreateFontIndirectExW(). *
  2099. * *
  2100. * Tue 04-Jun-1991 21:06:44 -by- Charles Whitmer [chuckwh] *
  2101. * Wrote it. *
  2102. \**************************************************************************/
  2103. HFONT WINAPI CreateFontIndirectA(CONST LOGFONTA *plf)
  2104. {
  2105. ENUMLOGFONTEXDVW elfw;
  2106. if (plf == (LPLOGFONTA) NULL)
  2107. return ((HFONT) 0);
  2108. vConvertLogFont(&elfw,(LOGFONTA *) plf);
  2109. if (GetAppCompatFlags2(VER40) & GACF2_DEFAULTCHARSET)
  2110. {
  2111. if (!_wcsicmp(elfw.elfEnumLogfontEx.elfLogFont.lfFaceName, L"OCR-A"))
  2112. elfw.elfEnumLogfontEx.elfLogFont.lfCharSet = (BYTE) DEFAULT_CHARSET;
  2113. }
  2114. return(CreateFontIndirectExW(&elfw));
  2115. }
  2116. /******************************Public*Routine******************************\
  2117. * CreateFont *
  2118. * *
  2119. * Client side stub. *
  2120. * *
  2121. * Tue 04-Jun-1991 21:06:44 -by- Charles Whitmer [chuckwh] *
  2122. * Wrote it. *
  2123. \**************************************************************************/
  2124. HFONT WINAPI
  2125. CreateFontA(
  2126. int cHeight,
  2127. int cWidth,
  2128. int cEscapement,
  2129. int cOrientation,
  2130. int cWeight,
  2131. DWORD bItalic,
  2132. DWORD bUnderline,
  2133. DWORD bStrikeOut,
  2134. DWORD iCharSet,
  2135. DWORD iOutPrecision,
  2136. DWORD iClipPrecision,
  2137. DWORD iQuality,
  2138. DWORD iPitchAndFamily,
  2139. LPCSTR pszFaceName
  2140. )
  2141. {
  2142. LOGFONTA lf;
  2143. lf.lfHeight = (LONG) cHeight;
  2144. lf.lfWidth = (LONG) cWidth;
  2145. lf.lfEscapement = (LONG) cEscapement;
  2146. lf.lfOrientation = (LONG) cOrientation;
  2147. lf.lfWeight = (LONG) cWeight;
  2148. lf.lfItalic = (BYTE) bItalic;
  2149. lf.lfUnderline = (BYTE) bUnderline;
  2150. lf.lfStrikeOut = (BYTE) bStrikeOut;
  2151. lf.lfCharSet = (BYTE) iCharSet;
  2152. lf.lfOutPrecision = (BYTE) iOutPrecision;
  2153. lf.lfClipPrecision = (BYTE) iClipPrecision;
  2154. lf.lfQuality = (BYTE) iQuality;
  2155. lf.lfPitchAndFamily = (BYTE) iPitchAndFamily;
  2156. {
  2157. INT jj;
  2158. // Copy the facename if pointer not NULL.
  2159. if (pszFaceName != (LPSTR) NULL)
  2160. {
  2161. for (jj=0; jj<LF_FACESIZE; jj++)
  2162. {
  2163. if( ( lf.lfFaceName[jj] = pszFaceName[jj] ) == 0 )
  2164. {
  2165. break;
  2166. }
  2167. }
  2168. }
  2169. else
  2170. {
  2171. // If NULL pointer, substitute a NULL string.
  2172. lf.lfFaceName[0] = '\0';
  2173. }
  2174. }
  2175. return(CreateFontIndirectA(&lf));
  2176. }
  2177. /******************************Public*Routine******************************\
  2178. * HFONT WINAPI CreateFontIndirectW(LPLOGFONTW plfw) *
  2179. * *
  2180. * History: *
  2181. * Fri 16-Aug-1991 14:12:44 by Kirk Olynyk [kirko] *
  2182. * Now uses CreateFontIndirectExW(). *
  2183. * *
  2184. * 13-Aug-1991 -by- Bodin Dresevic [BodinD] *
  2185. * Wrote it. *
  2186. \**************************************************************************/
  2187. HFONT WINAPI CreateFontIndirectW(CONST LOGFONTW *plfw)
  2188. {
  2189. ENUMLOGFONTEXDVW elfw;
  2190. if (plfw == (LPLOGFONTW) NULL)
  2191. return ((HFONT) 0);
  2192. vConvertLogFontW(&elfw,(LOGFONTW *)plfw);
  2193. if (GetAppCompatFlags2(VER40) & GACF2_DEFAULTCHARSET)
  2194. {
  2195. if (!_wcsicmp(elfw.elfEnumLogfontEx.elfLogFont.lfFaceName, L"OCR-A"))
  2196. elfw.elfEnumLogfontEx.elfLogFont.lfCharSet = (BYTE) DEFAULT_CHARSET;
  2197. }
  2198. return(CreateFontIndirectExW(&elfw));
  2199. }
  2200. /******************************Public*Routine******************************\
  2201. * HFONT WINAPI CreateFontW, UNICODE version of CreateFont *
  2202. * *
  2203. * History: *
  2204. * 13-Aug-1991 -by- Bodin Dresevic [BodinD] *
  2205. * Wrote it. *
  2206. \**************************************************************************/
  2207. HFONT WINAPI CreateFontW
  2208. (
  2209. int cHeight,
  2210. int cWidth,
  2211. int cEscapement,
  2212. int cOrientation,
  2213. int cWeight,
  2214. DWORD bItalic,
  2215. DWORD bUnderline,
  2216. DWORD bStrikeOut,
  2217. DWORD iCharSet,
  2218. DWORD iOutPrecision,
  2219. DWORD iClipPrecision,
  2220. DWORD iQuality,
  2221. DWORD iPitchAndFamily,
  2222. LPCWSTR pwszFaceName
  2223. )
  2224. {
  2225. LOGFONTW lfw;
  2226. lfw.lfHeight = (LONG) cHeight;
  2227. lfw.lfWidth = (LONG) cWidth;
  2228. lfw.lfEscapement = (LONG) cEscapement;
  2229. lfw.lfOrientation = (LONG) cOrientation;
  2230. lfw.lfWeight = (LONG) cWeight;
  2231. lfw.lfItalic = (BYTE) bItalic;
  2232. lfw.lfUnderline = (BYTE) bUnderline;
  2233. lfw.lfStrikeOut = (BYTE) bStrikeOut;
  2234. lfw.lfCharSet = (BYTE) iCharSet;
  2235. lfw.lfOutPrecision = (BYTE) iOutPrecision;
  2236. lfw.lfClipPrecision = (BYTE) iClipPrecision;
  2237. lfw.lfQuality = (BYTE) iQuality;
  2238. lfw.lfPitchAndFamily = (BYTE) iPitchAndFamily;
  2239. {
  2240. INT jj;
  2241. // Copy the facename if pointer not NULL.
  2242. if (pwszFaceName != (LPWSTR) NULL)
  2243. {
  2244. for (jj=0; jj<LF_FACESIZE; jj++)
  2245. {
  2246. if( ( lfw.lfFaceName[jj] = pwszFaceName[jj] ) == (WCHAR) 0 )
  2247. {
  2248. break;
  2249. }
  2250. }
  2251. }
  2252. else
  2253. {
  2254. // If NULL pointer, substitute a NULL string.
  2255. lfw.lfFaceName[0] = L'\0';
  2256. }
  2257. }
  2258. return(CreateFontIndirectW(&lfw));
  2259. }
  2260. /******************************Public*Routine******************************\
  2261. * CreateFontIndirectExA *
  2262. * *
  2263. * Client side stub. *
  2264. * *
  2265. * History: *
  2266. * 31-Jan-1992 -by- Gilman Wong [gilmanw] *
  2267. * Wrote it. *
  2268. \**************************************************************************/
  2269. HFONT WINAPI CreateFontIndirectExA(CONST ENUMLOGFONTEXDVA *pelf)
  2270. {
  2271. ENUMLOGFONTEXDVW elfw;
  2272. if (!pelf)
  2273. return ((HFONT) 0);
  2274. vConvertEnumLogFontExDvAtoW(&elfw, (ENUMLOGFONTEXDVA *)pelf);
  2275. if (GetAppCompatFlags2(VER40) & GACF2_DEFAULTCHARSET)
  2276. {
  2277. if (!_wcsicmp(elfw.elfEnumLogfontEx.elfLogFont.lfFaceName, L"OCR-A"))
  2278. elfw.elfEnumLogfontEx.elfLogFont.lfCharSet = (BYTE) DEFAULT_CHARSET;
  2279. }
  2280. return(CreateFontIndirectExW(&elfw));
  2281. }
  2282. /******************************Public*Routine******************************\
  2283. * UnrealizeObject
  2284. *
  2285. * This nukes the realization for a object.
  2286. *
  2287. * History:
  2288. * 16-May-1993 -by- Patrick Haluptzok patrickh
  2289. * Wrote it.
  2290. \**************************************************************************/
  2291. BOOL WINAPI UnrealizeObject(HANDLE h)
  2292. {
  2293. BOOL bRet = FALSE;
  2294. FIXUP_HANDLE(h);
  2295. // Validate the object. Only need to handle palettes.
  2296. if (LO_TYPE(h) == LO_BRUSH_TYPE)
  2297. {
  2298. bRet = TRUE;
  2299. }
  2300. else
  2301. {
  2302. bRet = NtGdiUnrealizeObject(h);
  2303. }
  2304. return(bRet);
  2305. }
  2306. /******************************Public*Routine******************************\
  2307. * DeleteObject()
  2308. *
  2309. \**************************************************************************/
  2310. BOOL META DeleteObject (HANDLE h)
  2311. {
  2312. BOOL bRet = TRUE;
  2313. INT iType = GRE_TYPE(h);
  2314. BOOL bValidate;
  2315. BOOL bDynamicNonStock;
  2316. LOCALFONT *plf = NULL; // essental initialization
  2317. FIXUP_HANDLEZ(h);
  2318. VALIDATE_HANDLE_AND_STOCK (bValidate, h, iType, bDynamicNonStock);
  2319. if (!bValidate)
  2320. {
  2321. if (!bValidate)
  2322. return (0);
  2323. }
  2324. if (iType != DC_TYPE)
  2325. {
  2326. if ((LO_TYPE(h) == LO_METAFILE16_TYPE) || (LO_TYPE(h) == LO_METAFILE_TYPE))
  2327. {
  2328. return(FALSE);
  2329. }
  2330. else if (LO_TYPE(h) == LO_REGION_TYPE)
  2331. {
  2332. return(DeleteRegion(h));
  2333. }
  2334. else if (LO_TYPE(h) == LO_ICMLCS_TYPE)
  2335. {
  2336. // ATTENTION: Win95 does not allow delete ColorSpace by DeleteObject()
  2337. // This might causes imcompatibility... but keep consistant
  2338. // with other GDI objects
  2339. return(DeleteColorSpace(h));
  2340. }
  2341. else if (IS_STOCKOBJ(h))
  2342. {
  2343. // Don't delete a stock object, just return TRUE for 3.1 compatibility.
  2344. return(TRUE);
  2345. }
  2346. else
  2347. {
  2348. // Inform the metafile if it knows this object.
  2349. if (pmetalink16Get(h) != NULL)
  2350. {
  2351. // must recheck the metalink because MF_DeleteObject might delete it
  2352. if (!MF_DeleteObject(h) ||
  2353. (pmetalink16Get(h) && !MF16_DeleteObject(h)))
  2354. {
  2355. return(FALSE);
  2356. }
  2357. }
  2358. // handle delete LogFont
  2359. if (LO_TYPE(h) == LO_FONT_TYPE)
  2360. {
  2361. PSHARED_GET_VALIDATE(plf,h,LFONT_TYPE);
  2362. if (plf)
  2363. {
  2364. // we always force deletion of the client side memory even if
  2365. // the font is still selected in some dc's. All that means is that
  2366. // text api's will have to go through the slow code paths in this
  2367. // pathological case.
  2368. vDeleteLOCALFONT(plf);
  2369. }
  2370. }
  2371. if (bDynamicNonStock)
  2372. h = (HANDLE)((ULONG_PTR)h|GDISTOCKOBJ);
  2373. // handle deletebrush
  2374. if (
  2375. (LO_TYPE(h) == LO_BRUSH_TYPE) ||
  2376. (LO_TYPE(h) == LO_PEN_TYPE)
  2377. )
  2378. {
  2379. PBRUSHATTR pBrushattr;
  2380. PSHARED_GET_VALIDATE(pBrushattr,h,BRUSH_TYPE);
  2381. if (
  2382. (bDynamicNonStock) ||
  2383. ((pBrushattr) &&
  2384. (!(pBrushattr->AttrFlags & (ATTR_CACHED|ATTR_TO_BE_DELETED|ATTR_CANT_SELECT))))
  2385. )
  2386. {
  2387. BEGIN_BATCH(BatchTypeDeleteBrush,BATCHDELETEBRUSH);
  2388. if (!bDynamicNonStock)
  2389. pBrushattr->AttrFlags |= ATTR_CANT_SELECT;
  2390. pBatch->Type = BatchTypeDeleteBrush;
  2391. pBatch->Length = sizeof(BATCHDELETEBRUSH);
  2392. pBatch->hbrush = h;
  2393. COMPLETE_BATCH_COMMAND();
  2394. return(TRUE);
  2395. }
  2396. }
  2397. // handle delete bitmap
  2398. if (LO_TYPE(h) == LO_BITMAP_TYPE)
  2399. {
  2400. // PCACHED_COLORSPACE pColorSpace;
  2401. //
  2402. // if this bitmap has thier own color space delete it, too.
  2403. //
  2404. // [NOTE:] Only DIB section can has a thier own color space,
  2405. // then, if we can identify this is DIB section or not from
  2406. // client side, we can optimize this call for non-DIB section case.
  2407. //
  2408. // pColorSpace = IcmGetColorSpaceforBitmap(h);
  2409. //
  2410. // if (pColorSpace)
  2411. // {
  2412. // IcmReleaseColorSpace((HGDIOBJ)h,pColorSpace,TRUE);
  2413. // }
  2414. //
  2415. //
  2416. // Release any color space associated to this bitmap.
  2417. //
  2418. IcmReleaseCachedColorSpace((HGDIOBJ)h);
  2419. }
  2420. }
  2421. UNBATCHED_COMMAND:
  2422. bRet = NtGdiDeleteObjectApp(h);
  2423. #if DBG
  2424. if (bRet && (LO_TYPE(h) == LO_FONT_TYPE))
  2425. {
  2426. PSHARED_GET_VALIDATE(plf,h,LFONT_TYPE);
  2427. ASSERTGDI(plf == NULL, "DeleteFont: plf nonzero after deletion\n");
  2428. }
  2429. #endif
  2430. }
  2431. else
  2432. {
  2433. bRet = DeleteDC(h);
  2434. }
  2435. return(bRet);
  2436. }
  2437. /**************************************************************************\
  2438. * SelectObject
  2439. *
  2440. * Thu 06-Jun-1991 00:58:46 -by- Charles Whitmer [chuckwh]
  2441. * Wrote it.
  2442. \**************************************************************************/
  2443. HANDLE META SelectObject(HDC hdc,HANDLE h)
  2444. {
  2445. HANDLE hRet = 0;
  2446. HDC *phdc;
  2447. FLONG fl;
  2448. INT iType;
  2449. PDC_ATTR pdcattr = NULL;
  2450. BOOL bValid;
  2451. FIXUP_HANDLE(hdc);
  2452. FIXUP_HANDLE_NOW(h);
  2453. VALIDATE_HANDLE(bValid, h, GRE_TYPE(h));
  2454. if (!bValid)
  2455. {
  2456. return (HANDLE)0;
  2457. }
  2458. iType = LO_TYPE(h);
  2459. // Palettes isn't allowed
  2460. if (iType == LO_PALETTE_TYPE)
  2461. {
  2462. SetLastError(ERROR_INVALID_FUNCTION);
  2463. return (HANDLE)0;
  2464. }
  2465. // Do region first so that it is not metafiled twice.
  2466. if (iType == LO_REGION_TYPE)
  2467. {
  2468. LONG_PTR iRet = ExtSelectClipRgn(hdc,h,RGN_COPY);
  2469. return((HANDLE)iRet);
  2470. }
  2471. else if (iType == LO_ICMLCS_TYPE)
  2472. {
  2473. return(SetColorSpace(hdc,h));
  2474. }
  2475. //
  2476. // Metafile the call.
  2477. //
  2478. if (IS_ALTDC_TYPE(hdc))
  2479. {
  2480. PLDC pldc;
  2481. if (IS_METADC16_TYPE(hdc))
  2482. return(MF16_SelectObject(hdc, h));
  2483. DC_PLDC(hdc,pldc,0);
  2484. if (pldc->iType == LO_METADC)
  2485. {
  2486. if (!MF_SelectAnyObject(hdc,h,EMR_SELECTOBJECT))
  2487. return((HANDLE) 0);
  2488. }
  2489. }
  2490. PSHARED_GET_VALIDATE(pdcattr,hdc,DC_TYPE);
  2491. if (pdcattr)
  2492. {
  2493. switch (iType)
  2494. {
  2495. case LO_EXTPEN_TYPE:
  2496. if (bNeedTranslateColor(pdcattr))
  2497. {
  2498. return(IcmSelectExtPen(hdc,pdcattr,h));
  2499. }
  2500. //hRet = NtGdiSelectPen(hdc,(HPEN)h);
  2501. pdcattr->ulDirty_ |= DC_PEN_DIRTY;
  2502. hRet = pdcattr->hpen;
  2503. pdcattr->hpen = h;
  2504. break;
  2505. case LO_PEN_TYPE:
  2506. if (bNeedTranslateColor(pdcattr))
  2507. {
  2508. return(IcmSelectPen(hdc,pdcattr,h));
  2509. }
  2510. //
  2511. // Always set the dirty flag to
  2512. // make sure the brush is checked in
  2513. // the kernel. For example, NEW_COLOR, might be set.
  2514. //
  2515. pdcattr->ulDirty_ |= DC_PEN_DIRTY;
  2516. hRet = pdcattr->hpen;
  2517. pdcattr->hpen = h;
  2518. break;
  2519. case LO_BRUSH_TYPE:
  2520. if (bNeedTranslateColor(pdcattr))
  2521. {
  2522. return(IcmSelectBrush(hdc,pdcattr,h));
  2523. }
  2524. //
  2525. // Always set the dirty flag to
  2526. // make sure the brush is checked in
  2527. // the kernel. For example, NEW_COLOR, might be set.
  2528. //
  2529. pdcattr->ulDirty_ |= DC_BRUSH_DIRTY;
  2530. hRet = pdcattr->hbrush;
  2531. pdcattr->hbrush = h;
  2532. break;
  2533. case LO_BITMAP_TYPE:
  2534. {
  2535. BOOL bDIBSelected;
  2536. //
  2537. // Currently DIB section is selected ?
  2538. //
  2539. bDIBSelected = bDIBSectionSelected(pdcattr);
  2540. //
  2541. // Select bitmap into DC.
  2542. //
  2543. hRet = NtGdiSelectBitmap(hdc,(HBITMAP)h);
  2544. if (hRet)
  2545. {
  2546. //
  2547. // DDB to DDB case, color space never has been changed.
  2548. //
  2549. if (bDIBSelected || bDIBSectionSelected(pdcattr))
  2550. {
  2551. //
  2552. // Marks the color space might be changed.
  2553. //
  2554. pdcattr->ulDirty_ |= (DIRTY_COLORSPACE|DIRTY_COLORTRANSFORM);
  2555. //
  2556. // if ICM is currently turned-ON, update now.
  2557. //
  2558. if (IS_ICM_INSIDEDC(pdcattr->lIcmMode))
  2559. {
  2560. //
  2561. // Destination bitmap surface has been changed,
  2562. // then need to update destination color space and
  2563. // color transform.
  2564. //
  2565. IcmUpdateDCColorInfo(hdc,pdcattr);
  2566. }
  2567. }
  2568. }
  2569. }
  2570. break;
  2571. case LO_FONT_TYPE:
  2572. {
  2573. UINT uiIndex = HANDLE_TO_INDEX(h);
  2574. PENTRY pentry = NULL;
  2575. pentry = &pGdiSharedHandleTable[uiIndex];
  2576. if (pentry->Flags & HMGR_ENTRY_LAZY_DEL)
  2577. {
  2578. hRet = 0;
  2579. }
  2580. else
  2581. {
  2582. hRet = pdcattr->hlfntNew;
  2583. if (DIFFHANDLE(hRet, h))
  2584. {
  2585. pdcattr->ulDirty_ |= DIRTY_CHARSET;
  2586. pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
  2587. pdcattr->hlfntNew = h;
  2588. //
  2589. // batch selectfont, to ensure ref count is correct when
  2590. // deletefont comes in
  2591. // we have to allow lazy deletion.
  2592. //
  2593. BEGIN_BATCH_HDC(hdc,pdcattr,BatchTypeSelectFont,BATCHSELECTFONT);
  2594. pBatch->hFont = h;
  2595. COMPLETE_BATCH_COMMAND();
  2596. return ((HANDLE)hRet);
  2597. UNBATCHED_COMMAND:
  2598. return(NtGdiSelectFont(hdc,h));
  2599. }
  2600. }
  2601. }
  2602. break;
  2603. default:
  2604. break;
  2605. }
  2606. }
  2607. else
  2608. {
  2609. WARNING("Bad DC passed to SelectObject\n");
  2610. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2611. hRet = 0;
  2612. }
  2613. return((HANDLE) hRet);
  2614. }
  2615. /******************************Public*Routine******************************\
  2616. * GetCurrentObject *
  2617. * *
  2618. * Client side routine. *
  2619. * *
  2620. * 03-Oct-1991 00:58:46 -by- John Colleran [johnc] *
  2621. * Wrote it. *
  2622. \**************************************************************************/
  2623. HANDLE WINAPI GetCurrentObject(HDC hdc, UINT iObjectType)
  2624. {
  2625. HANDLE hRet;
  2626. FIXUP_HANDLE(hdc);
  2627. switch (iObjectType)
  2628. {
  2629. case OBJ_BRUSH:
  2630. iObjectType = LO_BRUSH_TYPE;
  2631. break;
  2632. case OBJ_PEN:
  2633. case OBJ_EXTPEN:
  2634. iObjectType = LO_PEN_TYPE;
  2635. break;
  2636. case OBJ_FONT:
  2637. iObjectType = LO_FONT_TYPE;
  2638. break;
  2639. case OBJ_PAL:
  2640. iObjectType = LO_PALETTE_TYPE;
  2641. break;
  2642. case OBJ_BITMAP:
  2643. iObjectType = LO_BITMAP_TYPE;
  2644. break;
  2645. case OBJ_COLORSPACE:
  2646. iObjectType = LO_ICMLCS_TYPE;
  2647. break;
  2648. default:
  2649. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2650. return((HANDLE) 0);
  2651. }
  2652. hRet = GetDCObject(hdc, iObjectType);
  2653. return(hRet);
  2654. }
  2655. /******************************Public*Routine******************************\
  2656. * GetStockObject *
  2657. * *
  2658. * A simple function which looks the object up in a table. *
  2659. * *
  2660. \**************************************************************************/
  2661. HANDLE
  2662. GetStockObject(
  2663. int iObject)
  2664. {
  2665. //
  2666. // if it is in range, 0 - PRIV_STOCK_LAST, and we have gotten the stock
  2667. // objects, return the handle. Otherwise fail.
  2668. //
  2669. //
  2670. // WINBUG #82871 2-7-2000 bhouse Possible bug in GetStockObject
  2671. // Old Comment:
  2672. // - what about our private stock bitmap ??
  2673. //
  2674. // NOTE we should make this table part of the shared section since it is
  2675. // used by all applications.
  2676. //
  2677. if ((ULONG)iObject <= PRIV_STOCK_LAST)
  2678. {
  2679. if ((HANDLE) ahStockObjects[iObject] == NULL)
  2680. {
  2681. //
  2682. // If the kernel transition fails, the return value
  2683. // may actually an NTSTATUS return value such as
  2684. // STATUS_INVALID_SYSTEM_SERVICE (this has happened
  2685. // under rare stress scenarios).
  2686. //
  2687. // If we return the occasional bad handle under stress,
  2688. // so be it, but we shouldn't cache these bad handles
  2689. // in gdi32.dll. So do validation before accepting
  2690. // the handle.
  2691. //
  2692. HANDLE h = NtGdiGetStockObject(iObject);
  2693. BOOL bValid;
  2694. VALIDATE_HANDLE(bValid, h, GRE_TYPE(h));
  2695. if (bValid)
  2696. {
  2697. ahStockObjects[iObject] = (ULONG_PTR) h;
  2698. }
  2699. }
  2700. return((HANDLE) ahStockObjects[iObject]);
  2701. }
  2702. else
  2703. {
  2704. return((HANDLE)0);
  2705. }
  2706. }
  2707. /******************************Public*Routine******************************\
  2708. * EqualRgn *
  2709. * *
  2710. * Client side stub. *
  2711. * *
  2712. * Thu 06-Jun-1991 00:58:46 -by- Charles Whitmer [chuckwh] *
  2713. * Wrote it. *
  2714. \**************************************************************************/
  2715. BOOL WINAPI EqualRgn(HRGN hrgnA,HRGN hrgnB)
  2716. {
  2717. FIXUP_HANDLE(hrgnA);
  2718. FIXUP_HANDLE(hrgnB);
  2719. return(NtGdiEqualRgn(hrgnA,hrgnB));
  2720. }
  2721. /******************************Public*Routine******************************\
  2722. * GetBitmapDimensionEx *
  2723. * *
  2724. * Client side stub. *
  2725. * *
  2726. * Thu 06-Jun-1991 00:58:46 -by- Charles Whitmer [chuckwh] *
  2727. * Wrote it. *
  2728. \**************************************************************************/
  2729. BOOL WINAPI GetBitmapDimensionEx(HBITMAP hbm,LPSIZE psizl)
  2730. {
  2731. FIXUP_HANDLE(hbm);
  2732. return(NtGdiGetBitmapDimension(hbm, psizl));
  2733. }
  2734. /******************************Public*Routine******************************\
  2735. * GetNearestPaletteIndex
  2736. *
  2737. * Client side stub.
  2738. *
  2739. * Sat 31-Aug-1991 -by- Patrick Haluptzok [patrickh]
  2740. * Change to UINT
  2741. *
  2742. * Thu 06-Jun-1991 00:58:46 -by- Charles Whitmer [chuckwh]
  2743. * Wrote it.
  2744. \**************************************************************************/
  2745. UINT WINAPI GetNearestPaletteIndex(HPALETTE hpal,COLORREF color)
  2746. {
  2747. FIXUP_HANDLE(hpal);
  2748. return(NtGdiGetNearestPaletteIndex(hpal,color));
  2749. }
  2750. /******************************Public*Routine******************************\
  2751. * ULONG cchCutOffStrLen(PSZ pwsz, ULONG cCutOff)
  2752. *
  2753. * search for terminating zero but make sure not to slipp off the edge,
  2754. * return value counts in the term. zero if one is found
  2755. *
  2756. *
  2757. * History:
  2758. * 22-Aug-1991 -by- Bodin Dresevic [BodinD]
  2759. * Wrote it.
  2760. \**************************************************************************/
  2761. ULONG cchCutOffStrLen(PSZ psz, ULONG cCutOff)
  2762. {
  2763. ULONG cch;
  2764. for(cch = 0; cch < cCutOff; cch++)
  2765. {
  2766. if (*psz++ == 0)
  2767. return(cch); // terminating NULL is NOT included in count!
  2768. }
  2769. return(cCutOff);
  2770. }
  2771. /******************************Public*Routine******************************\
  2772. * ULONG cwcCutOffStrLen(PWSZ pwsz, ULONG cCutOff)
  2773. *
  2774. * search for terminating zero but make sure not to slipp off the edge,
  2775. * return value counts in the term. zero if one is found
  2776. *
  2777. *
  2778. * History:
  2779. * 22-Aug-1991 -by- Bodin Dresevic [BodinD]
  2780. * Wrote it.
  2781. \**************************************************************************/
  2782. ULONG cwcCutOffStrLen(PWSZ pwsz, ULONG cCutOff)
  2783. {
  2784. ULONG cwc;
  2785. for(cwc = 0; cwc < cCutOff; cwc++)
  2786. {
  2787. if (*pwsz++ == 0)
  2788. return(cwc + 1); // include the terminating NULL
  2789. }
  2790. return(cCutOff);
  2791. }
  2792. /******************************Public*Routine******************************\
  2793. * int cjGetNonFontObject()
  2794. *
  2795. * Does a GetObject on all objects that are not fonts.
  2796. *
  2797. * History:
  2798. * 19-Mar-1992 -by- J. Andrew Goossen [andrewgo]
  2799. * Wrote it.
  2800. \**************************************************************************/
  2801. int cjGetNonFontObject(HANDLE h, int c, LPVOID pv)
  2802. {
  2803. int cRet = 0;
  2804. int cGet = c;
  2805. int iType;
  2806. iType = LO_TYPE(h);
  2807. ASSERTGDI(iType != LO_FONT_TYPE, "Can't handle fonts");
  2808. if (iType == LO_REGION_TYPE)
  2809. {
  2810. GdiSetLastError(ERROR_INVALID_HANDLE);
  2811. return(cRet);
  2812. }
  2813. if (pv == NULL)
  2814. {
  2815. if (iType == LO_BRUSH_TYPE)
  2816. {
  2817. return(sizeof(LOGBRUSH));
  2818. }
  2819. else if (iType == LO_PEN_TYPE)
  2820. {
  2821. return(sizeof(LOGPEN));
  2822. }
  2823. }
  2824. FIXUP_HANDLE_NOW (h);
  2825. cRet = NtGdiExtGetObjectW(h,c,pv);
  2826. return(cRet);
  2827. }
  2828. /******************************Public*Routine******************************\
  2829. * int WINAPI GetObjectW(HANDLE h,int c,LPVOID pv)
  2830. *
  2831. * History:
  2832. * 07-Dec-1994 -by- Lingyun Wang [lingyunw]
  2833. * Wrote it.
  2834. \**************************************************************************/
  2835. int WINAPI GetObjectW(HANDLE h,int c,LPVOID pv)
  2836. {
  2837. int cRet = 0;
  2838. FIXUP_HANDLEZ(h);
  2839. switch (LO_TYPE(h))
  2840. {
  2841. case LO_ALTDC_TYPE:
  2842. case LO_DC_TYPE:
  2843. case LO_METAFILE16_TYPE:
  2844. case LO_METAFILE_TYPE:
  2845. GdiSetLastError(ERROR_INVALID_HANDLE);
  2846. cRet = 0;
  2847. break;
  2848. case LO_FONT_TYPE:
  2849. if (pv == (LPVOID) NULL)
  2850. {
  2851. return(sizeof(LOGFONTW));
  2852. }
  2853. if (c > (int)sizeof(ENUMLOGFONTEXDVW))
  2854. c = (int)sizeof(ENUMLOGFONTEXDVW);
  2855. cRet = NtGdiExtGetObjectW(h,c,pv);
  2856. break;
  2857. case LO_ICMLCS_TYPE:
  2858. if (GetLogColorSpaceW(h,pv,c))
  2859. {
  2860. cRet = sizeof(LOGCOLORSPACEW);
  2861. }
  2862. break;
  2863. default:
  2864. cRet = cjGetNonFontObject(h,c,pv);
  2865. break;
  2866. }
  2867. return(cRet);
  2868. }
  2869. /******************************Public*Routine******************************\
  2870. * int WINAPI GetObjectA(HANDLE h,int c,LPVOID pv)
  2871. *
  2872. * History:
  2873. * 07-Dec-1994 -by- Lingyun Wang [lingyunw]
  2874. * Wrote it.
  2875. \**************************************************************************/
  2876. int WINAPI GetObjectA(HANDLE h,int c,LPVOID pv)
  2877. {
  2878. int cRet = 0;
  2879. FIXUP_HANDLEZ(h);
  2880. switch (LO_TYPE(h))
  2881. {
  2882. case LO_ALTDC_TYPE:
  2883. case LO_DC_TYPE:
  2884. case LO_METAFILE16_TYPE:
  2885. case LO_METAFILE_TYPE:
  2886. GdiSetLastError(ERROR_INVALID_HANDLE);
  2887. return(0);
  2888. case LO_FONT_TYPE:
  2889. break;
  2890. case LO_ICMLCS_TYPE:
  2891. if (GetLogColorSpaceA(h,pv,c))
  2892. {
  2893. cRet = sizeof(LOGCOLORSPACEW);
  2894. }
  2895. break;
  2896. default:
  2897. return(cjGetNonFontObject(h,c,pv));
  2898. }
  2899. // Now handle only font objects:
  2900. if (pv)
  2901. {
  2902. ENUMLOGFONTEXDVW elfw;
  2903. cRet = NtGdiExtGetObjectW(h,sizeof(ENUMLOGFONTEXDVW),&elfw);
  2904. if (cRet)
  2905. {
  2906. // we shall optimize usual cases when the caller is asking the whole thing
  2907. //
  2908. // Hack, Hack:Office ME 97 call GetObjectA with a pointer to LOGFONTA and
  2909. // specify c = sizeof(LOGFONTW) by mistake, But it use to work under NT 4
  2910. // Then what we do here is check this case and still return the sizeof(LOGFONTA)
  2911. //
  2912. if ((c == sizeof(LOGFONTA)) || (c == sizeof(LOGFONTW)))
  2913. {
  2914. if (bConvertLogFontWToLogFontA((LOGFONTA *)pv,
  2915. &elfw.elfEnumLogfontEx.elfLogFont))
  2916. {
  2917. cRet = sizeof(LOGFONTA);
  2918. }
  2919. else
  2920. {
  2921. cRet = 0;
  2922. }
  2923. }
  2924. else if (c == sizeof(ENUMLOGFONTEXA))
  2925. {
  2926. if (bConvertEnumLogFontExWToEnumLogFontExA((ENUMLOGFONTEXA*)pv, &elfw.elfEnumLogfontEx))
  2927. {
  2928. cRet = c;
  2929. }
  2930. else
  2931. {
  2932. cRet = 0;
  2933. }
  2934. }
  2935. else if (c == sizeof(ENUMLOGFONTEXDVA))
  2936. {
  2937. if (bConvertEnumLogFontExWToEnumLogFontExA((ENUMLOGFONTEXA*)pv, &elfw.elfEnumLogfontEx))
  2938. {
  2939. // copy out design vector
  2940. RtlMoveMemory(&((ENUMLOGFONTEXDVA*)pv)->elfDesignVector,
  2941. &elfw.elfDesignVector,
  2942. SIZEOFDV(elfw.elfDesignVector.dvNumAxes));
  2943. cRet = c;
  2944. }
  2945. else
  2946. {
  2947. cRet = 0;
  2948. }
  2949. }
  2950. else // general case
  2951. {
  2952. ENUMLOGFONTEXDVA elfa;
  2953. c = min(c,sizeof(ENUMLOGFONTEXDVA));
  2954. if (bConvertEnumLogFontExWToEnumLogFontExA(&elfa.elfEnumLogfontEx,
  2955. &elfw.elfEnumLogfontEx))
  2956. {
  2957. // copy out design vector
  2958. RtlMoveMemory(&elfa.elfDesignVector,
  2959. &elfw.elfDesignVector,
  2960. SIZEOFDV(elfw.elfDesignVector.dvNumAxes));
  2961. cRet = c;
  2962. RtlMoveMemory(pv,&elfa,cRet);
  2963. }
  2964. else
  2965. {
  2966. cRet = 0;
  2967. }
  2968. }
  2969. }
  2970. }
  2971. else
  2972. {
  2973. cRet = sizeof(LOGFONTA);
  2974. }
  2975. return(cRet);
  2976. }
  2977. /******************************Public*Routine******************************\
  2978. * GetObjectType(HANDLE)
  2979. *
  2980. * History:
  2981. * 25-Jul-1991 -by- Eric Kutter [erick]
  2982. * Wrote it.
  2983. \**************************************************************************/
  2984. DWORD alPublicTypes[] =
  2985. {
  2986. 0, // LO_NULL,
  2987. OBJ_DC, // LO_DC,
  2988. OBJ_ENHMETADC // LO_METADC,
  2989. };
  2990. DWORD GetObjectType(HGDIOBJ h)
  2991. {
  2992. DWORD dwRet = 0;
  2993. UINT uiIndex;
  2994. FIXUP_HANDLE(h);
  2995. uiIndex = HANDLE_TO_INDEX(h);
  2996. if (uiIndex < MAX_HANDLE_COUNT)
  2997. {
  2998. PENTRY pentry = &pGdiSharedHandleTable[uiIndex];
  2999. if (
  3000. (pentry->FullUnique == (USHORT)((ULONG_PTR)h >> 16)) &&
  3001. ((OBJECTOWNER_PID(pentry->ObjectOwner) == gW32PID) ||
  3002. (OBJECTOWNER_PID(pentry->ObjectOwner) == 0))
  3003. )
  3004. {
  3005. switch (LO_TYPE(h))
  3006. {
  3007. case LO_BRUSH_TYPE:
  3008. dwRet = OBJ_BRUSH;
  3009. break;
  3010. case LO_REGION_TYPE:
  3011. dwRet = OBJ_REGION;
  3012. break;
  3013. case LO_PEN_TYPE:
  3014. dwRet = OBJ_PEN;
  3015. break;
  3016. case LO_EXTPEN_TYPE:
  3017. dwRet = OBJ_EXTPEN;
  3018. break;
  3019. case LO_FONT_TYPE:
  3020. dwRet = OBJ_FONT;
  3021. break;
  3022. case LO_BITMAP_TYPE:
  3023. dwRet = OBJ_BITMAP;
  3024. break;
  3025. case LO_PALETTE_TYPE:
  3026. dwRet = OBJ_PAL;
  3027. break;
  3028. case LO_METAFILE16_TYPE:
  3029. dwRet = OBJ_METAFILE;
  3030. break;
  3031. case LO_METAFILE_TYPE:
  3032. dwRet = OBJ_ENHMETAFILE;
  3033. break;
  3034. case LO_METADC16_TYPE:
  3035. dwRet = OBJ_METADC;
  3036. break;
  3037. case LO_DC_TYPE:
  3038. if( GetDCDWord( h, DDW_ISMEMDC, FALSE ) )
  3039. {
  3040. dwRet = OBJ_MEMDC;
  3041. }
  3042. else
  3043. {
  3044. dwRet = OBJ_DC;
  3045. }
  3046. break;
  3047. case LO_ALTDC_TYPE:
  3048. {
  3049. PLDC pldc;
  3050. DC_PLDC(h,pldc,0);
  3051. if (pldc->fl & LDC_META_PRINT)
  3052. {
  3053. //
  3054. // While we are doing EMF spooling, we lie to
  3055. // application to the HDC is real DC, not metafile
  3056. // DC, even it is actually metafile DC.
  3057. //
  3058. // This resolve the problem with Office97 + WordArt.
  3059. //
  3060. // (Raid #98810: WordArt doesn't print correctly to PS
  3061. // printers when EMF spooling is turned on)
  3062. //
  3063. dwRet = OBJ_DC;
  3064. }
  3065. else
  3066. {
  3067. dwRet = alPublicTypes[pldc->iType];
  3068. }
  3069. }
  3070. break;
  3071. case LO_ICMLCS_TYPE:
  3072. dwRet = OBJ_COLORSPACE;
  3073. break;
  3074. default:
  3075. GdiSetLastError(ERROR_INVALID_HANDLE);
  3076. break;
  3077. }
  3078. }
  3079. }
  3080. return(dwRet);
  3081. }
  3082. /******************************Public*Routine******************************\
  3083. * ResizePalette *
  3084. * *
  3085. * Client side stub. *
  3086. * *
  3087. * Warning: *
  3088. * The pv field of a palette's LHE is used to determine if a palette *
  3089. * has been modified since it was last realized. SetPaletteEntries *
  3090. * and ResizePalette will increment this field after they have *
  3091. * modified the palette. It is only updated for metafiled palettes *
  3092. * *
  3093. * Thu 06-Jun-1991 00:58:46 -by- Charles Whitmer [chuckwh] *
  3094. * Wrote it. *
  3095. \**************************************************************************/
  3096. BOOL WINAPI ResizePalette(HPALETTE hpal,UINT c)
  3097. {
  3098. ULONG bRet = FALSE;
  3099. PMETALINK16 pml16;
  3100. FIXUP_HANDLE(hpal);
  3101. // Inform the metafile if it knows this object.
  3102. if (pml16 = pmetalink16Get(hpal))
  3103. {
  3104. if (LO_TYPE(hpal) != LO_PALETTE_TYPE)
  3105. return(bRet);
  3106. if (!MF_ResizePalette(hpal,c))
  3107. return(bRet);
  3108. if (!MF16_ResizePalette(hpal,c))
  3109. return(bRet);
  3110. // Mark the palette as changed (for 16-bit metafile tracking)
  3111. pml16->pv = (PVOID)(((ULONG_PTR)pml16->pv)++);
  3112. }
  3113. return(NtGdiResizePalette(hpal,c));
  3114. }
  3115. /******************************Public*Routine******************************\
  3116. * SetBitmapDimensionEx *
  3117. * *
  3118. * Client side stub. *
  3119. * *
  3120. * Thu 06-Jun-1991 00:58:46 -by- Charles Whitmer [chuckwh] *
  3121. * Wrote it. *
  3122. \**************************************************************************/
  3123. BOOL WINAPI SetBitmapDimensionEx
  3124. (
  3125. HBITMAP hbm,
  3126. int cx,
  3127. int cy,
  3128. LPSIZE psizl
  3129. )
  3130. {
  3131. FIXUP_HANDLE(hbm);
  3132. return(NtGdiSetBitmapDimension(hbm, cx, cy, psizl));
  3133. }
  3134. /******************************Public*Routine******************************\
  3135. * GetMetaRgn *
  3136. * *
  3137. * Client side stub. *
  3138. * *
  3139. * Fri Apr 10 10:12:36 1992 -by- Hock San Lee [hockl] *
  3140. * Wrote it. *
  3141. \**************************************************************************/
  3142. int WINAPI GetMetaRgn(HDC hdc,HRGN hrgn)
  3143. {
  3144. FIXUP_HANDLE(hdc);
  3145. FIXUP_HANDLE(hrgn);
  3146. return(GetRandomRgn(hdc, hrgn, 2)); // hrgnMeta
  3147. }
  3148. /******************************Private*Routine******************************\
  3149. * GdiSetLastError *
  3150. * *
  3151. * Client side private function. *
  3152. * *
  3153. \**************************************************************************/
  3154. VOID GdiSetLastError(ULONG iError)
  3155. {
  3156. #if DBG_X
  3157. PSZ psz;
  3158. switch (iError)
  3159. {
  3160. case ERROR_INVALID_HANDLE:
  3161. psz = "ERROR_INVALID_HANDLE";
  3162. break;
  3163. case ERROR_NOT_ENOUGH_MEMORY:
  3164. psz = "ERROR_NOT_ENOUGH_MEMORY";
  3165. break;
  3166. case ERROR_INVALID_PARAMETER:
  3167. psz = "ERROR_INVALID_PARAMETER";
  3168. break;
  3169. case ERROR_BUSY:
  3170. psz = "ERROR_BUSY";
  3171. break;
  3172. default:
  3173. psz = "unknown error code";
  3174. break;
  3175. }
  3176. KdPrint(( "GDI Err: %s = 0x%04X\n",psz,(USHORT) iError ));
  3177. #endif
  3178. NtCurrentTeb()->LastErrorValue = iError;
  3179. }
  3180. /******************************Public*Routine******************************\
  3181. * ExtCreateRegion
  3182. *
  3183. * Upload a region to the server
  3184. *
  3185. * History:
  3186. * 29-Oct-1991 -by- Donald Sidoroff [donalds]
  3187. * Wrote it.
  3188. \**************************************************************************/
  3189. HRGN WINAPI ExtCreateRegion(
  3190. CONST XFORM * lpXform,
  3191. DWORD nCount,
  3192. CONST RGNDATA * lpRgnData)
  3193. {
  3194. ULONG ulRet;
  3195. if (lpRgnData == (LPRGNDATA) NULL)
  3196. {
  3197. GdiSetLastError(ERROR_INVALID_PARAMETER);
  3198. return((HRGN) 0);
  3199. }
  3200. //
  3201. // Perf: use CreateRectRgn when possible
  3202. //
  3203. if ((lpXform == NULL) && (lpRgnData->rdh.nCount == 1))
  3204. {
  3205. RECT * prcl = (RECT *)(lpRgnData->Buffer);
  3206. return (CreateRectRgn(prcl->left, prcl->top, prcl->right, prcl->bottom));
  3207. }
  3208. else
  3209. {
  3210. return(NtGdiExtCreateRegion((LPXFORM)lpXform, nCount, (LPRGNDATA)lpRgnData));
  3211. }
  3212. }
  3213. /******************************Public*Routine******************************\
  3214. * MonoBitmap(hbr)
  3215. *
  3216. * Test if a brush is monochrome
  3217. *
  3218. * History:
  3219. * 09-Mar-1992 -by- Donald Sidoroff [donalds]
  3220. * Wrote it.
  3221. \**************************************************************************/
  3222. BOOL MonoBitmap(HBITMAP hbm)
  3223. {
  3224. return(NtGdiMonoBitmap(hbm));
  3225. }
  3226. /******************************Public*Routine******************************\
  3227. * GetObjectBitmapHandle(hbr)
  3228. *
  3229. * Get the SERVER handle of the bitmap used to create the brush or pen.
  3230. *
  3231. * History:
  3232. * 09-Mar-1992 -by- Donald Sidoroff [donalds]
  3233. * Wrote it.
  3234. \**************************************************************************/
  3235. HBITMAP GetObjectBitmapHandle(
  3236. HBRUSH hbr,
  3237. UINT *piUsage)
  3238. {
  3239. FIXUP_HANDLE(hbr);
  3240. return(NtGdiGetObjectBitmapHandle(hbr,piUsage));
  3241. }
  3242. /******************************Public*Routine******************************\
  3243. * EnumObjects
  3244. *
  3245. * Calls the NtGdiEnumObjects function twice: once to determine the number of
  3246. * objects to be enumerated, and a second time to fill a buffer with the
  3247. * objects.
  3248. *
  3249. * The callback function is called for each of the objects in the buffer.
  3250. * The enumeration will be prematurely terminated if the callback function
  3251. * returns 0.
  3252. *
  3253. * Returns:
  3254. * The last callback return value. Meaning is user defined. ERROR if
  3255. * an error occurs.
  3256. *
  3257. * History:
  3258. * 25-Mar-1992 -by- Gilman Wong [gilmanw]
  3259. * Wrote it.
  3260. \**************************************************************************/
  3261. int EnumObjects (
  3262. HDC hdc,
  3263. int iObjectType,
  3264. GOBJENUMPROC lpObjectFunc,
  3265. #ifdef STRICT
  3266. LPARAM lpData
  3267. #else
  3268. LPVOID lpData
  3269. #endif
  3270. )
  3271. {
  3272. int iRet = ERROR;
  3273. ULONG cjObject; // size of a single object
  3274. ULONG cObjects; // number of objects to process
  3275. ULONG cjBuf; // size of buffer (in BYTEs)
  3276. PVOID pvBuf; // object buffer; do callbacks with pointers into this buffer
  3277. PBYTE pjObj, pjObjEnd;// pointers into callback buffer
  3278. FIXUP_HANDLE(hdc);
  3279. // Determine size of object.
  3280. switch (iObjectType)
  3281. {
  3282. case OBJ_PEN:
  3283. cjObject = sizeof(LOGPEN);
  3284. break;
  3285. case OBJ_BRUSH:
  3286. cjObject = sizeof(LOGBRUSH);
  3287. break;
  3288. default:
  3289. WARNING1("gdi!EnumObjects(): bad object type\n");
  3290. GdiSetLastError(ERROR_INVALID_PARAMETER);
  3291. return iRet;
  3292. }
  3293. // Call NtGdiEnumObjects to determine number of objects.
  3294. if ( (cObjects = NtGdiEnumObjects(hdc, iObjectType, 0, (PVOID) NULL)) == 0 )
  3295. {
  3296. WARNING("gdi!EnumObjects(): error, no objects\n");
  3297. return iRet;
  3298. }
  3299. // Allocate buffer for callbacks.
  3300. cjBuf = cObjects * cjObject;
  3301. if ( (pvBuf = (PVOID) LOCALALLOC(cjBuf)) == (PVOID) NULL )
  3302. {
  3303. WARNING("gdi!EnumObjects(): error allocating callback buffer\n");
  3304. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3305. return iRet;
  3306. }
  3307. // Call NtGdiEnumObjects to fill buffer.
  3308. // Note: while NtGdiEnumObjects will never return a count more than the size of
  3309. // the buffer (this would be an ERROR condition), it might return less.
  3310. if ( (cObjects = NtGdiEnumObjects(hdc, iObjectType, cjBuf, pvBuf)) == 0 )
  3311. {
  3312. WARNING("gdi!EnumObjects(): error filling callback buffer\n");
  3313. LOCALFREE(pvBuf);
  3314. return iRet;
  3315. }
  3316. // Process callbacks.
  3317. pjObj = (PBYTE) pvBuf;
  3318. pjObjEnd = (PBYTE) pvBuf + cjBuf;
  3319. for (; pjObj < pjObjEnd; pjObj += cjObject)
  3320. {
  3321. // Terminate early if callback returns 0.
  3322. if ( (iRet = (*lpObjectFunc)((LPVOID) pjObj, lpData)) == 0 )
  3323. break;
  3324. }
  3325. // Release callback buffer.
  3326. LOCALFREE(pvBuf);
  3327. // Return last callback return value.
  3328. return iRet;
  3329. }
  3330. /**********************************************************************\
  3331. * GetDCObject *
  3332. * Get Server side DC objects *
  3333. * *
  3334. * 14-11-94 -by- Lingyun Wang [lingyunw] *
  3335. * Wrote it *
  3336. \**********************************************************************/
  3337. HANDLE GetDCObject (HDC hdc, int iType)
  3338. {
  3339. if (
  3340. (iType == LO_BRUSH_TYPE) ||
  3341. (iType == LO_PEN_TYPE) ||
  3342. (iType == LO_EXTPEN_TYPE) ||
  3343. (iType == LO_ICMLCS_TYPE)
  3344. )
  3345. {
  3346. PDC_ATTR pdca;
  3347. HANDLE iret = 0;
  3348. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  3349. if (pdca != NULL)
  3350. {
  3351. switch (iType)
  3352. {
  3353. case LO_BRUSH_TYPE:
  3354. iret = pdca->hbrush;
  3355. break;
  3356. case LO_PEN_TYPE:
  3357. case LO_EXTPEN_TYPE:
  3358. iret = pdca->hpen;
  3359. break;
  3360. case LO_ICMLCS_TYPE:
  3361. iret = pdca->hColorSpace;
  3362. break;
  3363. }
  3364. }
  3365. return(iret);
  3366. }
  3367. else
  3368. {
  3369. return(NtGdiGetDCObject(hdc,iType));
  3370. }
  3371. }
  3372. /******************************Public*Routine******************************\
  3373. * HANDLE CreateClientObj()
  3374. *
  3375. * History:
  3376. * 18-Jan-1995 -by- Eric Kutter [erick]
  3377. * Wrote it.
  3378. \**************************************************************************/
  3379. HANDLE CreateClientObj(
  3380. ULONG ulType)
  3381. {
  3382. return(NtGdiCreateClientObj(ulType));
  3383. }
  3384. /******************************Public*Routine******************************\
  3385. * BOOL DeleteClientObj()
  3386. *
  3387. * History:
  3388. * 18-Jan-1995 -by- Eric Kutter [erick]
  3389. * Wrote it.
  3390. \**************************************************************************/
  3391. BOOL DeleteClientObj(
  3392. HANDLE h)
  3393. {
  3394. return(NtGdiDeleteClientObj(h));
  3395. }
  3396. /******************************Public*Routine******************************\
  3397. * BOOL MakeInfoDC()
  3398. *
  3399. * Temporarily make a printer DC a INFO DC. This is used to be able to
  3400. * associate a metafile with a printer DC.
  3401. *
  3402. * bSet = TRUE - set as info
  3403. * FALSE - restore
  3404. *
  3405. * History:
  3406. * 19-Jan-1995 -by- Eric Kutter [erick]
  3407. * Wrote it.
  3408. \**************************************************************************/
  3409. BOOL MakeInfoDC(
  3410. HDC hdc,
  3411. BOOL bSet)
  3412. {
  3413. FIXUP_HANDLE(hdc);
  3414. return(NtGdiMakeInfoDC(hdc,bSet));
  3415. }