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.

605 lines
16 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. *
  13. \***************************************************************************/
  14. #include <windows.h>
  15. #include "dll.h"
  16. #include "pict.h"
  17. extern int maxPixelsX, maxPixelsY;
  18. void INTERNAL GetHimetricUnits(HBITMAP, LPPOINT);
  19. #pragma alloc_text(_TEXT, BmSaveToStream, BmStreamWrite, BmLoadFromStream, BmStreamRead, GetBytes, PutBytes, PutStrWithLen, BmQueryBounds, BmChangeData, BmCopy, BmDuplicate, BmUpdateStruct, GetHimetricUnits)
  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. ErrQueryRelease,
  57. ErrRequestData, // requestdata
  58. ErrObjectLong, // objectLong
  59. BmChangeData // change data of the existing object
  60. };
  61. OLESTATUS FARINTERNAL BmRelease (lpobj)
  62. LPOBJECT_BM lpobj;
  63. {
  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 (lpobj, lpstream)
  79. LPOBJECT_BM lpobj;
  80. LPOLESTREAM lpstream;
  81. {
  82. if (!lpobj->hBitmap || !lpobj->sizeBytes)
  83. return OLE_ERROR_BLANK;
  84. if (PutBytes (lpstream, (LPSTR) &dwVerToFile, sizeof(LONG)))
  85. return OLE_ERROR_STREAM;
  86. if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG)))
  87. return OLE_ERROR_STREAM;
  88. if (PutStrWithLen(lpstream, (LPSTR)"BITMAP"))
  89. return OLE_ERROR_STREAM;
  90. if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) {
  91. if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG)))
  92. if (!PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD)))
  93. return BmStreamWrite (lpstream, lpobj);
  94. }
  95. return OLE_ERROR_STREAM;
  96. }
  97. OLESTATUS FARINTERNAL BmClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj)
  98. LPOBJECT_BM lpobjsrc;
  99. LPOLECLIENT lpclient;
  100. LHCLIENTDOC lhclientdoc;
  101. LPSTR lpobjname;
  102. LPOBJECT_BM FAR * lplpobj;
  103. {
  104. if (!CheckClientDoc ((LPCLIENTDOC)lhclientdoc))
  105. return OLE_ERROR_HANDLE;
  106. if (!(*lplpobj = BmCreateObject (lpobjsrc->hBitmap, lpclient, FALSE,
  107. lhclientdoc, lpobjname, lpobjsrc->head.ctype)))
  108. return OLE_ERROR_MEMORY;
  109. else
  110. return OLE_OK;
  111. }
  112. OLESTATUS FARINTERNAL BmEqual (lpobj1, lpobj2)
  113. LPOBJECT_BM lpobj1;
  114. LPOBJECT_BM lpobj2;
  115. {
  116. HANDLE hBits1 = NULL, hBits2 = NULL;
  117. LPSTR lpBits1 = NULL, lpBits2 = NULL;
  118. OLESTATUS retVal;
  119. DWORD dwBytes1, dwBytes2;
  120. if (lpobj1->sizeBytes != lpobj2->sizeBytes)
  121. return OLE_ERROR_NOT_EQUAL;
  122. retVal = OLE_ERROR_MEMORY;
  123. if (!(hBits1 = GlobalAlloc (GMEM_MOVEABLE, lpobj1->sizeBytes)))
  124. goto errEqual;
  125. if (!(lpBits1 = GlobalLock (hBits1)))
  126. goto errEqual;
  127. if (!(hBits2 = GlobalAlloc (GMEM_MOVEABLE, lpobj2->sizeBytes)))
  128. goto errEqual;
  129. if (!(lpBits2 = GlobalLock (hBits2)))
  130. goto errEqual;
  131. dwBytes1 = GetBitmapBits (lpobj1->hBitmap, lpobj1->sizeBytes, lpBits1);
  132. dwBytes2 = GetBitmapBits (lpobj2->hBitmap, lpobj2->sizeBytes, lpBits2);
  133. if (dwBytes1 != dwBytes2) {
  134. retVal = OLE_ERROR_NOT_EQUAL;
  135. goto errEqual;
  136. }
  137. // !!! UtilMemCmp has to be redone for >64k bitmaps
  138. if (UtilMemCmp (lpBits1, lpBits2, dwBytes1))
  139. retVal = OLE_ERROR_NOT_EQUAL;
  140. else
  141. retVal = OLE_OK;
  142. errEqual:
  143. if (lpBits1)
  144. GlobalUnlock (hBits1);
  145. if (lpBits2)
  146. GlobalUnlock (hBits2);
  147. if (hBits1)
  148. GlobalFree (hBits1);
  149. if (hBits2)
  150. GlobalFree (hBits2);
  151. return retVal;
  152. }
  153. OLESTATUS FARINTERNAL BmCopy (lpobj)
  154. LPOBJECT_BM lpobj;
  155. {
  156. HBITMAP hBitmap;
  157. DWORD size;
  158. if (!lpobj->hBitmap)
  159. return OLE_ERROR_BLANK;
  160. if(!(hBitmap = BmDuplicate (lpobj->hBitmap, &size, NULL)))
  161. return OLE_ERROR_MEMORY;
  162. SetClipboardData(CF_BITMAP, hBitmap);
  163. return OLE_OK;
  164. }
  165. OLESTATUS FARINTERNAL BmQueryBounds (lpobj, lpRc)
  166. LPOBJECT_BM lpobj;
  167. LPRECT lpRc;
  168. {
  169. Puts("BmQueryBounds");
  170. if (!lpobj->hBitmap)
  171. return OLE_ERROR_BLANK;
  172. lpRc->left = 0;
  173. lpRc->top = 0;
  174. lpRc->right = (int) lpobj->head.cx;
  175. lpRc->bottom = (int) lpobj->head.cy;
  176. return OLE_OK;
  177. }
  178. OLECLIPFORMAT FARINTERNAL BmEnumFormat (lpobj, cfFormat)
  179. LPOBJECT_BM lpobj;
  180. OLECLIPFORMAT cfFormat;
  181. {
  182. if (!cfFormat)
  183. return CF_BITMAP;
  184. return NULL;
  185. }
  186. OLESTATUS FARINTERNAL BmGetData (lpobj, cfFormat, lphandle)
  187. LPOBJECT_BM lpobj;
  188. OLECLIPFORMAT cfFormat;
  189. LPHANDLE lphandle;
  190. {
  191. if (cfFormat != CF_BITMAP)
  192. return OLE_ERROR_FORMAT;
  193. if (!(*lphandle = lpobj->hBitmap))
  194. return OLE_ERROR_BLANK;
  195. return OLE_OK;
  196. }
  197. OLESTATUS FARINTERNAL BmLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, lplpoleobject, objType)
  198. LPOLESTREAM lpstream;
  199. LPOLECLIENT lpclient;
  200. LHCLIENTDOC lhclientdoc;
  201. LPSTR lpobjname;
  202. LPOLEOBJECT FAR * lplpoleobject;
  203. LONG objType;
  204. {
  205. LPOBJECT_BM lpobj = NULL;
  206. *lplpoleobject = NULL;
  207. if (!(lpobj = BmCreateBlank (lhclientdoc, lpobjname, objType)))
  208. return OLE_ERROR_MEMORY;
  209. lpobj->head.lpclient = lpclient;
  210. if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) {
  211. if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG)))
  212. if (!GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD)))
  213. if (BmStreamRead (lpstream, lpobj)) {
  214. *lplpoleobject = (LPOLEOBJECT)lpobj;
  215. return OLE_OK;
  216. }
  217. }
  218. OleDelete ((LPOLEOBJECT)lpobj);
  219. return OLE_ERROR_STREAM;;
  220. }
  221. OLESTATUS INTERNAL BmStreamWrite (lpstream, lpobj)
  222. LPOLESTREAM lpstream;
  223. LPOBJECT_BM lpobj;
  224. {
  225. HANDLE hBits;
  226. LPSTR lpBits;
  227. int retVal = OLE_ERROR_STREAM;
  228. BITMAP bm;
  229. DWORD dwSize; // size of bit array
  230. dwSize = lpobj->sizeBytes - sizeof(BITMAP);
  231. if (hBits = GlobalAlloc (GMEM_MOVEABLE, dwSize)) {
  232. if (lpBits = (LPSTR) GlobalLock (hBits)) {
  233. if (GetBitmapBits (lpobj->hBitmap, dwSize, lpBits)) {
  234. GetObject (lpobj->hBitmap, sizeof(BITMAP), (LPSTR) &bm);
  235. if (!PutBytes (lpstream, (LPSTR) &bm, sizeof(BITMAP)))
  236. if (!PutBytes (lpstream, (LPSTR) lpBits, dwSize))
  237. retVal = OLE_OK;
  238. }
  239. GlobalUnlock(hBits);
  240. } else
  241. retVal = OLE_ERROR_MEMORY;
  242. GlobalFree(hBits);
  243. } else
  244. retVal = OLE_ERROR_MEMORY;
  245. return retVal;
  246. }
  247. BOOL INTERNAL BmStreamRead (lpstream, lpobj)
  248. LPOLESTREAM lpstream;
  249. LPOBJECT_BM lpobj;
  250. {
  251. HANDLE hBits;
  252. LPSTR lpBits;
  253. BOOL retVal = FALSE;
  254. BITMAP bm;
  255. POINT point;
  256. if (GetBytes (lpstream, (LPSTR)&bm, sizeof(BITMAP)))
  257. return FALSE;
  258. lpobj->sizeBytes = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) *
  259. ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel);
  260. if (hBits = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes)) {
  261. if (lpBits = (LPSTR) GlobalLock (hBits)) {
  262. if (!GetBytes(lpstream, lpBits, lpobj->sizeBytes)) {
  263. if (lpobj->hBitmap = CreateBitmap (bm.bmWidth,
  264. bm.bmHeight,
  265. bm.bmPlanes,
  266. bm.bmBitsPixel,
  267. lpBits)) {
  268. retVal = TRUE;
  269. lpobj->xSize = point.x = bm.bmWidth;
  270. lpobj->ySize = point.y = bm.bmHeight;
  271. // size of (bitmap header + bits)
  272. lpobj->sizeBytes += sizeof(BITMAP);
  273. #ifdef OLD
  274. // !!! We shouldn't do the conversion. The info should be
  275. // part of the stream.
  276. if (!lpobj->head.cx) {
  277. ConvertToHimetric (&point);
  278. lpobj->head.cx = (LONG) point.x;
  279. lpobj->head.cy = (LONG) point.y;
  280. }
  281. #endif
  282. }
  283. }
  284. GlobalUnlock(hBits);
  285. }
  286. GlobalFree(hBits);
  287. }
  288. return retVal;
  289. }
  290. OLESTATUS FARINTERNAL BmPaste (lpclient, lhclientdoc, lpobjname, lplpoleobject, objType)
  291. LPOLECLIENT lpclient;
  292. LHCLIENTDOC lhclientdoc;
  293. LPSTR lpobjname;
  294. LPOLEOBJECT FAR * lplpoleobject;
  295. LONG objType;
  296. {
  297. HBITMAP hBitmap;
  298. *lplpoleobject = NULL;
  299. if ((hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP)) == NULL)
  300. return OLE_ERROR_MEMORY;
  301. if (!(*lplpoleobject = (LPOLEOBJECT) BmCreateObject (hBitmap,
  302. lpclient, FALSE, lhclientdoc,
  303. lpobjname, objType)))
  304. return OLE_ERROR_MEMORY;
  305. return OLE_OK;
  306. }
  307. LPOBJECT_BM INTERNAL BmCreateObject (hBitmap, lpclient, fDelete, lhclientdoc, lpobjname, objType)
  308. HBITMAP hBitmap;
  309. LPOLECLIENT lpclient;
  310. BOOL fDelete;
  311. LHCLIENTDOC lhclientdoc;
  312. LPSTR lpobjname;
  313. LONG objType;
  314. {
  315. LPOBJECT_BM lpobj;
  316. if (lpobj = BmCreateBlank (lhclientdoc, lpobjname, objType)) {
  317. if (BmChangeData (lpobj, hBitmap, lpclient, fDelete) != OLE_OK) {
  318. BmRelease (lpobj);
  319. lpobj = NULL;
  320. }
  321. }
  322. return lpobj;
  323. }
  324. // If the routine fails then the object will be left with it's old data.
  325. // If fDelete is TRUE, then hNewBitmap will be deleted whether the routine
  326. // is successful or not.
  327. OLESTATUS FARINTERNAL BmChangeData (lpobj, hNewBitmap, lpclient, fDelete)
  328. LPOBJECT_BM lpobj;
  329. HBITMAP hNewBitmap;
  330. LPOLECLIENT lpclient;
  331. BOOL fDelete;
  332. {
  333. BITMAP bm;
  334. DWORD dwSize;
  335. HBITMAP hOldBitmap;
  336. hOldBitmap = lpobj->hBitmap;
  337. if (!fDelete) {
  338. if (!(hNewBitmap = BmDuplicate (hNewBitmap, &dwSize, &bm)))
  339. return OLE_ERROR_MEMORY;
  340. }
  341. else {
  342. if (!GetObject (hNewBitmap, sizeof(BITMAP), (LPSTR) &bm)) {
  343. DeleteObject (hNewBitmap);
  344. return OLE_ERROR_MEMORY;
  345. }
  346. dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) *
  347. ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel);
  348. }
  349. BmUpdateStruct (lpobj, lpclient, hNewBitmap, &bm, dwSize);
  350. if (hOldBitmap)
  351. DeleteObject (hOldBitmap);
  352. return OLE_OK;
  353. }
  354. void INTERNAL BmUpdateStruct (lpobj, lpclient, hBitmap, lpBm, dwBytes)
  355. LPOBJECT_BM lpobj;
  356. LPOLECLIENT lpclient;
  357. HBITMAP hBitmap;
  358. LPBITMAP lpBm;
  359. DWORD dwBytes;
  360. {
  361. POINT point;
  362. lpobj->head.lpclient = lpclient;
  363. lpobj->xSize = point.x = lpBm->bmWidth;
  364. lpobj->ySize = point.y = lpBm->bmHeight;
  365. GetHimetricUnits (hBitmap, &point);
  366. lpobj->head.cx = (LONG) point.x;
  367. lpobj->head.cy = (LONG) point.y;
  368. lpobj->sizeBytes = dwBytes + sizeof(BITMAP);
  369. lpobj->hBitmap = hBitmap;
  370. }
  371. LPOBJECT_BM FARINTERNAL BmCreateBlank (lhclientdoc, lpobjname, objType)
  372. LHCLIENTDOC lhclientdoc;
  373. LPSTR lpobjname;
  374. LONG objType;
  375. {
  376. HOBJECT hobj;
  377. LPOBJECT_BM lpobj;
  378. if ((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_BM)))
  379. == NULL)
  380. return NULL;
  381. if (!(lpobj = (LPOBJECT_BM) GlobalLock (hobj))){
  382. GlobalFree (hobj);
  383. return NULL;
  384. }
  385. lpobj->head.objId[0] = 'L';
  386. lpobj->head.objId[1] = 'E';
  387. lpobj->head.mm = MM_TEXT;
  388. lpobj->head.ctype = objType;
  389. lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblBM;
  390. lpobj->head.iTable = INVALID_INDEX;
  391. lpobj->head.hobj = hobj;
  392. if (objType == CT_STATIC)
  393. DocAddObject ((LPCLIENTDOC) lhclientdoc,
  394. (LPOLEOBJECT) lpobj, lpobjname);
  395. return lpobj;
  396. }
  397. HBITMAP FARINTERNAL BmDuplicate (hold, lpdwSize, lpBm)
  398. HBITMAP hold;
  399. DWORD FAR * lpdwSize;
  400. LPBITMAP lpBm;
  401. {
  402. HBITMAP hnew;
  403. HANDLE hMem;
  404. LPSTR lpMem;
  405. LONG retVal = TRUE;
  406. DWORD dwSize;
  407. BITMAP bm;
  408. DWORD dwExtents = NULL;
  409. // !!! another way to duplicate the bitmap
  410. GetObject (hold, sizeof(BITMAP), (LPSTR) &bm);
  411. dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) *
  412. ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel);
  413. if (!(hMem = GlobalAlloc (GMEM_MOVEABLE, dwSize)))
  414. return NULL;
  415. if (!(lpMem = GlobalLock (hMem))){
  416. GlobalFree (hMem);
  417. return NULL;
  418. }
  419. GetBitmapBits (hold, dwSize, lpMem);
  420. if (hnew = CreateBitmap (bm.bmWidth, bm.bmHeight,
  421. bm.bmPlanes, bm.bmBitsPixel, NULL))
  422. retVal = SetBitmapBits (hnew, dwSize, lpMem);
  423. GlobalUnlock (hMem);
  424. GlobalFree (hMem);
  425. if (hnew && (!retVal)) {
  426. DeleteObject (hnew);
  427. hnew = NULL;
  428. }
  429. *lpdwSize = dwSize;
  430. if (lpBm)
  431. *lpBm = bm;
  432. if (dwExtents = GetBitmapDimension (hold))
  433. SetBitmapDimension (hnew, LOWORD(dwExtents), HIWORD(dwExtents));
  434. return hnew;
  435. }
  436. void INTERNAL GetHimetricUnits(HBITMAP hBitmap, LPPOINT lpPoint)
  437. {
  438. HDC hdc;
  439. DWORD dwDim;
  440. if (dwDim = GetBitmapDimension (hBitmap)) {
  441. lpPoint->x = 10 * LOWORD(dwDim);
  442. lpPoint->y = - (10 * HIWORD(dwDim));
  443. return;
  444. }
  445. // clip if it exceeds maxPixels. Note that we have a limitation of
  446. // 0x8FFF HIMETRIC units in OLE1.0
  447. if (lpPoint->x > maxPixelsX)
  448. lpPoint->x = maxPixelsX;
  449. if (lpPoint->y > maxPixelsY)
  450. lpPoint->y = maxPixelsY;
  451. if (hdc = GetDC (NULL)) {
  452. lpPoint->x = MulDiv (lpPoint->x, 2540,
  453. GetDeviceCaps (hdc, LOGPIXELSX));
  454. lpPoint->y = - MulDiv (lpPoint->y, 2540,
  455. GetDeviceCaps (hdc, LOGPIXELSY));
  456. ReleaseDC (NULL, hdc);
  457. }
  458. else {
  459. lpPoint->x = 0;
  460. lpPoint->y = 0;
  461. }
  462. }