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.

628 lines
17 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: BM.C
  3. *
  4. * Handles all API routines for the bitmap sub-dll of the ole dll.
  5. *
  6. * Created: 1990
  7. *
  8. * Copyright (c) 1990, 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * Raor,Srinik (../../1990,91) Designed, coded
  12. * Curts create NT version
  13. *
  14. \***************************************************************************/
  15. #include <windows.h>
  16. #include "dll.h"
  17. #include "pict.h"
  18. extern int maxPixelsX, maxPixelsY;
  19. void INTERNAL GetHimetricUnits(HBITMAP, LPPOINT);
  20. OLEOBJECTVTBL vtblBM = {
  21. ErrQueryProtocol, // check whether the speced protocol is supported
  22. BmRelease, // Release
  23. ErrShow, // Show
  24. ErrPlay, // play
  25. BmGetData, // Get the object data
  26. ErrSetData, // Set the object data
  27. ErrSetTargetDevice,//
  28. ErrSetBounds, // set viewport bounds
  29. BmEnumFormat, // enumerate supported formats
  30. ErrSetColorScheme, //
  31. BmRelease, // delete
  32. ErrSetHostNames, //
  33. BmSaveToStream, // write to file
  34. BmClone, // clone object
  35. ErrCopyFromLink, // Create embedded from Link
  36. BmEqual, // compares the given objects for data equality
  37. BmCopy, // copy to clip
  38. BmDraw, // draw the object
  39. ErrActivate, // open
  40. ErrExecute, // excute
  41. ErrClose, // Stop
  42. ErrUpdate, // Update
  43. ErrReconnect, // Reconnect
  44. ErrObjectConvert, // convert object to specified type
  45. ErrGetUpdateOptions,// update options
  46. ErrSetUpdateOptions,// update options
  47. ObjRename, // Change Object name
  48. ObjQueryName, // Get current object name
  49. ObjQueryType, // Object type
  50. BmQueryBounds, // QueryBounds
  51. ObjQuerySize, // Find the size of the object
  52. ErrQueryOpen, // Query open
  53. ErrQueryOutOfDate, // query whether object is current
  54. ErrQueryRelease, // release related stuff
  55. ErrQueryRelease,
  56. ErrQueryReleaseMethod,
  57. ErrRequestData, // requestdata
  58. ErrObjectLong, // objectLong
  59. BmChangeData // change data of the existing object
  60. };
  61. OLESTATUS FARINTERNAL BmRelease (LPOLEOBJECT lpoleobj)
  62. {
  63. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  64. HOBJECT hobj;
  65. if (lpobj->hBitmap) {
  66. DeleteObject (lpobj->hBitmap);
  67. lpobj->hBitmap = NULL;
  68. }
  69. if (lpobj->head.lhclientdoc)
  70. DocDeleteObject ((LPOLEOBJECT) lpobj);
  71. if (hobj = lpobj->head.hobj){
  72. lpobj->head.hobj = NULL;
  73. GlobalUnlock (hobj);
  74. GlobalFree (hobj);
  75. }
  76. return OLE_OK;
  77. }
  78. OLESTATUS FARINTERNAL BmSaveToStream (
  79. LPOLEOBJECT lpoleobj,
  80. LPOLESTREAM lpstream
  81. ){
  82. DWORD dwFileVer = GetFileVersion(lpoleobj);
  83. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  84. DWORD dwSize = lpobj->sizeBytes - sizeof(BITMAP) + sizeof(WIN16BITMAP);
  85. if (!lpobj->hBitmap || !lpobj->sizeBytes)
  86. return OLE_ERROR_BLANK;
  87. if (PutBytes (lpstream, (LPSTR) &dwFileVer, sizeof(LONG)))
  88. return OLE_ERROR_STREAM;
  89. if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG)))
  90. return OLE_ERROR_STREAM;
  91. if (PutStrWithLen(lpstream, (LPSTR)"BITMAP"))
  92. return OLE_ERROR_STREAM;
  93. if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) {
  94. if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG)))
  95. if (!PutBytes (lpstream, (LPSTR) &dwSize, sizeof(DWORD)))
  96. return BmStreamWrite (lpstream, lpobj);
  97. }
  98. return OLE_ERROR_STREAM;
  99. }
  100. OLESTATUS FARINTERNAL BmClone (
  101. LPOLEOBJECT lpoleobj,
  102. LPOLECLIENT lpclient,
  103. LHCLIENTDOC lhclientdoc,
  104. OLE_LPCSTR lpobjname,
  105. LPOLEOBJECT FAR * lplpoleobj
  106. ){
  107. LPOBJECT_BM lpobjsrc = (LPOBJECT_BM)lpoleobj;
  108. LPOBJECT_BM FAR * lplpobj = (LPOBJECT_BM FAR *)lplpoleobj;
  109. if (!CheckClientDoc ((LPCLIENTDOC)lhclientdoc))
  110. return OLE_ERROR_HANDLE;
  111. if (!(*lplpobj = BmCreateObject (lpobjsrc->hBitmap, lpclient, FALSE,
  112. lhclientdoc, lpobjname,
  113. lpobjsrc->head.ctype)))
  114. return OLE_ERROR_MEMORY;
  115. else
  116. return OLE_OK;
  117. }
  118. OLESTATUS FARINTERNAL BmEqual (
  119. LPOLEOBJECT lpoleobj1,
  120. LPOLEOBJECT lpoleobj2
  121. ){
  122. LPOBJECT_BM lpobj1 = (LPOBJECT_BM)lpoleobj1;
  123. LPOBJECT_BM lpobj2 = (LPOBJECT_BM)lpoleobj2;
  124. HANDLE hBits1 = NULL, hBits2 = NULL;
  125. LPSTR lpBits1 = NULL, lpBits2 = NULL;
  126. OLESTATUS retVal;
  127. DWORD dwBytes1, dwBytes2;
  128. if (lpobj1->sizeBytes != lpobj2->sizeBytes)
  129. return OLE_ERROR_NOT_EQUAL;
  130. retVal = OLE_ERROR_MEMORY;
  131. if (!(hBits1 = GlobalAlloc (GMEM_MOVEABLE, lpobj1->sizeBytes)))
  132. goto errEqual;
  133. if (!(lpBits1 = GlobalLock (hBits1)))
  134. goto errEqual;
  135. if (!(hBits2 = GlobalAlloc (GMEM_MOVEABLE, lpobj2->sizeBytes)))
  136. goto errEqual;
  137. if (!(lpBits2 = GlobalLock (hBits2)))
  138. goto errEqual;
  139. dwBytes1 = GetBitmapBits (lpobj1->hBitmap, lpobj1->sizeBytes, lpBits1);
  140. dwBytes2 = GetBitmapBits (lpobj2->hBitmap, lpobj2->sizeBytes, lpBits2);
  141. if (dwBytes1 != dwBytes2) {
  142. retVal = OLE_ERROR_NOT_EQUAL;
  143. goto errEqual;
  144. }
  145. // !!! UtilMemCmp has to be redone for >64k bitmaps
  146. if (UtilMemCmp (lpBits1, lpBits2, dwBytes1))
  147. retVal = OLE_ERROR_NOT_EQUAL;
  148. else
  149. retVal = OLE_OK;
  150. errEqual:
  151. if (lpBits1)
  152. GlobalUnlock (hBits1);
  153. if (lpBits2)
  154. GlobalUnlock (hBits2);
  155. if (hBits1)
  156. GlobalFree (hBits1);
  157. if (hBits2)
  158. GlobalFree (hBits2);
  159. return retVal;
  160. }
  161. OLESTATUS FARINTERNAL BmCopy (
  162. LPOLEOBJECT lpoleobj
  163. ){
  164. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  165. HBITMAP hBitmap;
  166. DWORD size;
  167. if (!lpobj->hBitmap)
  168. return OLE_ERROR_BLANK;
  169. if(!(hBitmap = BmDuplicate (lpobj->hBitmap, &size, NULL)))
  170. return OLE_ERROR_MEMORY;
  171. SetClipboardData(CF_BITMAP, hBitmap);
  172. return OLE_OK;
  173. }
  174. OLESTATUS FARINTERNAL BmQueryBounds (
  175. LPOLEOBJECT lpoleobj,
  176. LPRECT lpRc
  177. ){
  178. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  179. Puts("BmQueryBounds");
  180. if (!lpobj->hBitmap)
  181. return OLE_ERROR_BLANK;
  182. lpRc->left = 0;
  183. lpRc->top = 0;
  184. lpRc->right = (int) lpobj->head.cx;
  185. lpRc->bottom = (int) lpobj->head.cy;
  186. return OLE_OK;
  187. }
  188. OLECLIPFORMAT FARINTERNAL BmEnumFormat (
  189. LPOLEOBJECT lpoleobj,
  190. OLECLIPFORMAT cfFormat
  191. ){
  192. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  193. if (!cfFormat)
  194. return CF_BITMAP;
  195. return 0;
  196. }
  197. OLESTATUS FARINTERNAL BmGetData (
  198. LPOLEOBJECT lpoleobj,
  199. OLECLIPFORMAT cfFormat,
  200. LPHANDLE lphandle
  201. ){
  202. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  203. if (cfFormat != CF_BITMAP)
  204. return OLE_ERROR_FORMAT;
  205. if (!(*lphandle = lpobj->hBitmap))
  206. return OLE_ERROR_BLANK;
  207. return OLE_OK;
  208. }
  209. OLESTATUS FARINTERNAL BmLoadFromStream (
  210. LPOLESTREAM lpstream,
  211. LPOLECLIENT lpclient,
  212. LHCLIENTDOC lhclientdoc,
  213. LPSTR lpobjname,
  214. LPOLEOBJECT FAR * lplpoleobject,
  215. LONG objType
  216. ){
  217. LPOBJECT_BM lpobj = NULL;
  218. *lplpoleobject = NULL;
  219. if (!(lpobj = BmCreateBlank (lhclientdoc, lpobjname, objType)))
  220. return OLE_ERROR_MEMORY;
  221. lpobj->head.lpclient = lpclient;
  222. if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) {
  223. if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG)))
  224. if (!GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD)))
  225. if (BmStreamRead (lpstream, lpobj)) {
  226. *lplpoleobject = (LPOLEOBJECT)lpobj;
  227. return OLE_OK;
  228. }
  229. }
  230. OleDelete ((LPOLEOBJECT)lpobj);
  231. return OLE_ERROR_STREAM;;
  232. }
  233. OLESTATUS INTERNAL BmStreamWrite (
  234. LPOLESTREAM lpstream,
  235. LPOBJECT_BM lpobj
  236. ){
  237. HANDLE hBits;
  238. LPSTR lpBits;
  239. int retVal = OLE_ERROR_STREAM;
  240. BITMAP bm;
  241. DWORD dwSize;
  242. dwSize = lpobj->sizeBytes - sizeof(BITMAP);
  243. if (hBits = GlobalAlloc (GMEM_MOVEABLE, dwSize)) {
  244. if (lpBits = (LPSTR) GlobalLock (hBits)) {
  245. if (GetBitmapBits (lpobj->hBitmap, dwSize, lpBits)) {
  246. WIN16BITMAP w16bm;
  247. GetObject (lpobj->hBitmap, sizeof(BITMAP), (LPSTR) &bm);
  248. ConvertBM32to16(&bm, &w16bm);
  249. if (!PutBytes (lpstream, (LPSTR) &w16bm, sizeof(WIN16BITMAP)))
  250. if (!PutBytes (lpstream, (LPSTR) lpBits, dwSize))
  251. retVal = OLE_OK;
  252. }
  253. GlobalUnlock(hBits);
  254. } else
  255. retVal = OLE_ERROR_MEMORY;
  256. GlobalFree(hBits);
  257. } else
  258. retVal = OLE_ERROR_MEMORY;
  259. return retVal;
  260. }
  261. BOOL INTERNAL BmStreamRead (
  262. LPOLESTREAM lpstream,
  263. LPOBJECT_BM lpobj
  264. ){
  265. HANDLE hBits;
  266. LPSTR lpBits;
  267. BOOL retVal = FALSE;
  268. BITMAP bm;
  269. WIN16BITMAP w16bm;
  270. POINT point;
  271. if (GetBytes (lpstream, (LPSTR)&w16bm, sizeof(WIN16BITMAP)))
  272. return FALSE;
  273. ConvertBM16to32(&w16bm,&bm);
  274. lpobj->sizeBytes -= sizeof(WIN16BITMAP) ;
  275. if (hBits = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes)) {
  276. if (lpBits = (LPSTR) GlobalLock (hBits)) {
  277. if (!GetBytes(lpstream, lpBits, lpobj->sizeBytes)) {
  278. if (lpobj->hBitmap = CreateBitmap (bm.bmWidth,
  279. bm.bmHeight,
  280. bm.bmPlanes,
  281. bm.bmBitsPixel,
  282. lpBits)) {
  283. retVal = TRUE;
  284. lpobj->xSize = point.x = bm.bmWidth;
  285. lpobj->ySize = point.y = bm.bmHeight;
  286. // size of (bitmap header + bits)
  287. lpobj->sizeBytes += sizeof(BITMAP);
  288. #ifdef OLD
  289. // !!! We shouldn't do the conversion. The info should be
  290. // part of the stream.
  291. if (!lpobj->head.cx) {
  292. ConvertToHimetric (&point);
  293. lpobj->head.cx = (LONG) point.x;
  294. lpobj->head.cy = (LONG) point.y;
  295. }
  296. #endif
  297. }
  298. }
  299. GlobalUnlock(hBits);
  300. }
  301. GlobalFree(hBits);
  302. }
  303. return retVal;
  304. }
  305. OLESTATUS FARINTERNAL BmPaste (
  306. LPOLECLIENT lpclient,
  307. LHCLIENTDOC lhclientdoc,
  308. LPSTR lpobjname,
  309. LPOLEOBJECT FAR * lplpoleobject,
  310. LONG objType
  311. ){
  312. HBITMAP hBitmap;
  313. *lplpoleobject = NULL;
  314. if ((hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP)) == NULL)
  315. return OLE_ERROR_MEMORY;
  316. if (!(*lplpoleobject = (LPOLEOBJECT) BmCreateObject (hBitmap,
  317. lpclient, FALSE, lhclientdoc,
  318. lpobjname, objType)))
  319. return OLE_ERROR_MEMORY;
  320. return OLE_OK;
  321. }
  322. LPOBJECT_BM INTERNAL BmCreateObject (
  323. HBITMAP hBitmap,
  324. LPOLECLIENT lpclient,
  325. BOOL fDelete,
  326. LHCLIENTDOC lhclientdoc,
  327. LPCSTR lpobjname,
  328. LONG objType
  329. ){
  330. LPOBJECT_BM lpobj;
  331. if (lpobj = BmCreateBlank (lhclientdoc, (LPSTR)lpobjname, objType)) {
  332. if (BmChangeData ((LPOLEOBJECT)lpobj, (HANDLE)hBitmap, lpclient, fDelete) != OLE_OK) {
  333. BmRelease ((LPOLEOBJECT)lpobj);
  334. lpobj = NULL;
  335. }
  336. }
  337. return lpobj;
  338. }
  339. // If the routine fails then the object will be left with it's old data.
  340. // If fDelete is TRUE, then hNewBitmap will be deleted whether the routine
  341. // is successful or not.
  342. OLESTATUS FARINTERNAL BmChangeData (
  343. LPOLEOBJECT lpoleobj,
  344. HANDLE hNewBitmap,
  345. LPOLECLIENT lpclient,
  346. BOOL fDelete
  347. ){
  348. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  349. BITMAP bm;
  350. DWORD dwSize;
  351. HBITMAP hOldBitmap;
  352. hOldBitmap = lpobj->hBitmap;
  353. if (!fDelete) {
  354. if (!(hNewBitmap = BmDuplicate (hNewBitmap, &dwSize, &bm)))
  355. return OLE_ERROR_MEMORY;
  356. }
  357. else {
  358. if (!GetObject (hNewBitmap, sizeof(BITMAP), (LPSTR) &bm)) {
  359. DeleteObject (hNewBitmap);
  360. return OLE_ERROR_MEMORY;
  361. }
  362. //*add get bitmap bits
  363. dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) *
  364. ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel);
  365. }
  366. BmUpdateStruct (lpobj, lpclient, hNewBitmap, &bm, dwSize);
  367. if (hOldBitmap)
  368. DeleteObject (hOldBitmap);
  369. return OLE_OK;
  370. }
  371. void INTERNAL BmUpdateStruct (
  372. LPOBJECT_BM lpobj,
  373. LPOLECLIENT lpclient,
  374. HBITMAP hBitmap,
  375. LPBITMAP lpBm,
  376. DWORD dwBytes
  377. ){
  378. POINT point;
  379. lpobj->head.lpclient = lpclient;
  380. lpobj->xSize = point.x = lpBm->bmWidth;
  381. lpobj->ySize = point.y = lpBm->bmHeight;
  382. GetHimetricUnits (hBitmap, &point);
  383. lpobj->head.cx = (LONG) point.x;
  384. lpobj->head.cy = (LONG) point.y;
  385. lpobj->sizeBytes = dwBytes + sizeof(BITMAP);
  386. lpobj->hBitmap = hBitmap;
  387. }
  388. LPOBJECT_BM FARINTERNAL BmCreateBlank (
  389. LHCLIENTDOC lhclientdoc,
  390. LPSTR lpobjname,
  391. LONG objType
  392. ){
  393. HOBJECT hobj;
  394. LPOBJECT_BM lpobj;
  395. if ((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_BM)))
  396. == NULL)
  397. return NULL;
  398. if (!(lpobj = (LPOBJECT_BM) GlobalLock (hobj))){
  399. GlobalFree (hobj);
  400. return NULL;
  401. }
  402. lpobj->head.objId[0] = 'L';
  403. lpobj->head.objId[1] = 'E';
  404. lpobj->head.mm = MM_TEXT;
  405. lpobj->head.ctype = objType;
  406. lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblBM;
  407. lpobj->head.iTable = INVALID_INDEX;
  408. lpobj->head.hobj = hobj;
  409. if (objType == CT_STATIC)
  410. DocAddObject ((LPCLIENTDOC) lhclientdoc,
  411. (LPOLEOBJECT) lpobj, lpobjname);
  412. return lpobj;
  413. }
  414. HBITMAP FARINTERNAL BmDuplicate (
  415. HBITMAP hold,
  416. DWORD FAR * lpdwSize,
  417. LPBITMAP lpBm
  418. ){
  419. HBITMAP hnew;
  420. HANDLE hMem;
  421. LPSTR lpMem;
  422. LONG retVal = TRUE;
  423. DWORD dwSize;
  424. BITMAP bm;
  425. INT iX,iY;
  426. // !!! another way to duplicate the bitmap
  427. GetObject (hold, sizeof(BITMAP), (LPSTR) &bm);
  428. dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) *
  429. ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel);
  430. if (!(hMem = GlobalAlloc (GMEM_MOVEABLE, dwSize)))
  431. return NULL;
  432. if (!(lpMem = GlobalLock (hMem))){
  433. GlobalFree (hMem);
  434. return NULL;
  435. }
  436. GetBitmapBits (hold, dwSize, lpMem);
  437. if (hnew = CreateBitmap (bm.bmWidth, bm.bmHeight,
  438. bm.bmPlanes, bm.bmBitsPixel, NULL)) {
  439. if (hnew) retVal = SetBitmapBits (hnew, dwSize, lpMem);
  440. }
  441. GlobalUnlock (hMem);
  442. GlobalFree (hMem);
  443. if (hnew && (!retVal)) {
  444. DeleteObject (hnew);
  445. hnew = NULL;
  446. }
  447. *lpdwSize = dwSize;
  448. if (lpBm)
  449. *lpBm = bm;
  450. if (MGetBitmapDimension (hold,&iX,&iY))
  451. if (hnew) MSetBitmapDimension (hnew, iX, iY);
  452. return hnew;
  453. }
  454. void INTERNAL GetHimetricUnits(HBITMAP hBitmap, LPPOINT lpPoint)
  455. {
  456. HDC hdc;
  457. INT iX,iY;
  458. MGetBitmapDimension (hBitmap,&iX,&iY);
  459. if (iX || iY) {
  460. lpPoint->x = 10 * iX;
  461. lpPoint->y = - (10 * iY);
  462. return;
  463. }
  464. // clip if it exceeds maxPixels. Note that we have a limitation of
  465. // 0x8FFF HIMETRIC units in OLE1.0
  466. if (lpPoint->x > maxPixelsX)
  467. lpPoint->x = maxPixelsX;
  468. if (lpPoint->y > maxPixelsY)
  469. lpPoint->y = maxPixelsY;
  470. if (hdc = GetDC (NULL)) {
  471. lpPoint->x = MulDiv (lpPoint->x, 2540,
  472. GetDeviceCaps (hdc, LOGPIXELSX));
  473. lpPoint->y = - MulDiv (lpPoint->y, 2540,
  474. GetDeviceCaps (hdc, LOGPIXELSY));
  475. ReleaseDC (NULL, hdc);
  476. }
  477. else {
  478. lpPoint->x = 0;
  479. lpPoint->y = 0;
  480. }
  481. }