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.

3587 lines
112 KiB

  1. /***************************************************************************\
  2. *
  3. * File: ApiStubs.cpp
  4. *
  5. * Description:
  6. * ApiStubs.cpp exposes all public DirectUser API's in the Win32 world.
  7. *
  8. *
  9. * History:
  10. * 1/18/2000: JStall: Created
  11. *
  12. * Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
  13. *
  14. \***************************************************************************/
  15. #include "stdafx.h"
  16. #include "WinAPI.h"
  17. #include "DwpEx.h"
  18. #define DUSER_API
  19. #pragma warning(disable: 4296) // expression is always false
  20. //
  21. // Undefine the macros declared in ObjectAPI because they will be redefined
  22. // here for the WinAPI handle-based API's.
  23. //
  24. #undef BEGIN_API
  25. #undef END_API
  26. #undef BEGIN_API_NOLOCK
  27. #undef END_API_NOLOCK
  28. #undef BEGIN_API_NOCONTEXT
  29. #undef END_API_NOCONTEXT
  30. #undef CHECK_MODIFY
  31. #undef VALIDATE_GADGETCONTEXT
  32. #undef VALIDATE_VALUE
  33. #undef VALIDATE_HWND
  34. #undef VALIDATE_REGION
  35. #undef VALIDATE_OBJECT
  36. #undef VALIDATE_EVENTGADGET
  37. #undef VALIDATE_EVENTGADGET_NOCONTEXT
  38. #undef VALIDATE_VISUAL
  39. #undef VALIDATE_ROOTGADGET
  40. #undef VALIDATE_VISUAL_OR_NULL
  41. #undef VALIDATE_TRANSITION
  42. #undef VALIDATE_FLAGS
  43. #undef VALIDATE_RANGE
  44. #undef VALIDATE_CODE_PTR
  45. #undef VALIDATE_CODE_PTR_OR_NULL
  46. #undef VALIDATE_READ_PTR
  47. #undef VALIDATE_READ_PTR_
  48. #undef VALIDATE_READ_PTR_OR_NULL_
  49. #undef VALIDATE_READ_STRUCT
  50. #undef VALIDATE_WRITE_PTR
  51. #undef VALIDATE_WRITE_PTR_
  52. #undef VALIDATE_WRITE_PTR_OR_NULL_
  53. #undef VALIDATE_WRITE_STRUCT
  54. #undef VALIDATE_STRING_PTR
  55. #undef VALIDATE_STRINGA_PTR
  56. #undef VALIDATE_STRINGW_PTR
  57. //
  58. // SET_RETURN is a convenient macro that converts from DirectUser error
  59. // conditions and sets up the return value.
  60. //
  61. // NOTE: This MUST be a macro (and not an inline function) because we CANNOT
  62. // evaluate success unless hr was actually successful. Unfortunately with
  63. // function calls, success would need to be evaluated to call the function.
  64. //
  65. #define SET_RETURN(hr, success) \
  66. do { \
  67. if (SUCCEEDED(hr)) { \
  68. retval = success; \
  69. } else { \
  70. SetError(hr); \
  71. } \
  72. } while (0) \
  73. template <class T>
  74. inline void SetError(T dwErr)
  75. {
  76. SetLastError((DWORD) dwErr);
  77. }
  78. //
  79. // API Entry / Exit setup rountines
  80. //
  81. #define BEGIN_RECV(type, value, defermsg) \
  82. type retval = value; \
  83. type errret = value; \
  84. UNREFERENCED_PARAMETER(errret); \
  85. \
  86. if (!IsInitContext()) { \
  87. PromptInvalid("Must initialize Context before using thread"); \
  88. SetError(DU_E_NOCONTEXT); \
  89. goto rawErrorExit; \
  90. } \
  91. \
  92. { \
  93. ContextLock cl; \
  94. if (!cl.LockNL(defermsg)) { \
  95. SetError(E_INVALIDARG); \
  96. goto ErrorExit; \
  97. } \
  98. Context * pctxThread = cl.pctx; \
  99. AssertInstance(pctxThread); \
  100. UNREFERENCED_PARAMETER(pctxThread); \
  101. #define END_RECV() \
  102. goto ErrorExit; \
  103. ErrorExit: \
  104. /* Unlocks the Context here */ \
  105. ; \
  106. } \
  107. rawErrorExit: \
  108. return retval;
  109. #define BEGIN_RECV_NOLOCK(type, value) \
  110. type retval = value; \
  111. type errret = value; \
  112. UNREFERENCED_PARAMETER(errret); \
  113. \
  114. if (!IsInitContext()) { \
  115. PromptInvalid("Must initialize Context before using thread"); \
  116. SetError(DU_E_NOCONTEXT); \
  117. goto rawErrorExit; \
  118. } \
  119. \
  120. { \
  121. Context * pctxThread = ::GetContext(); \
  122. AssertInstance(pctxThread); \
  123. #define END_RECV_NOLOCK() \
  124. goto ErrorExit; \
  125. ErrorExit: \
  126. ; \
  127. } \
  128. rawErrorExit: \
  129. return retval;
  130. #define BEGIN_RECV_NOCONTEXT(type, value) \
  131. type retval = value; \
  132. type errret = value; \
  133. UNREFERENCED_PARAMETER(errret); \
  134. #define END_RECV_NOCONTEXT() \
  135. goto ErrorExit; \
  136. ErrorExit: \
  137. return retval;
  138. #define CHECK_MODIFY() \
  139. if (pctxThread->IsReadOnly()) { \
  140. PromptInvalid("Can not call modifying function while in read-only state / callback"); \
  141. SetError(DU_E_READONLYCONTEXT); \
  142. goto ErrorExit; \
  143. } \
  144. //
  145. // Individual parameter validation rountines
  146. //
  147. #define VALIDATE_GADGETCONTEXT(gad) \
  148. { \
  149. Context * pctxGad = (p##gad)->GetContext(); \
  150. if (pctxThread != pctxGad) { \
  151. PromptInvalid("Must use Gadget inside correct Context"); \
  152. SetError(DU_E_INVALIDCONTEXT); \
  153. goto ErrorExit; \
  154. } \
  155. }
  156. #define VALIDATE_VALUE(x, v) \
  157. if (x != v) { \
  158. SetError(E_INVALIDARG); \
  159. goto ErrorExit; \
  160. }
  161. #define VALIDATE_HWND(wnd) \
  162. if ((h##wnd == NULL) || (!IsWindow(h##wnd))) { \
  163. PromptInvalid("Handle is not a valid Window"); \
  164. SetError(E_INVALIDARG); \
  165. goto ErrorExit; \
  166. }
  167. #define VALIDATE_REGION(rgn) \
  168. if (h##rgn == NULL) { \
  169. PromptInvalid("Handle is not a valid region"); \
  170. SetError(E_INVALIDARG); \
  171. goto ErrorExit; \
  172. }
  173. #define VALIDATE_OBJECT(obj) \
  174. { \
  175. p##obj = BaseObject::ValidateHandle(h##obj); \
  176. if (p##obj == NULL) { \
  177. PromptInvalid("Handle is not a valid object"); \
  178. SetError(E_INVALIDARG); \
  179. goto ErrorExit; \
  180. } \
  181. }
  182. #define VALIDATE_EVENTGADGET(gad) \
  183. { \
  184. p##gad = ValidateBaseGadget(h##gad); \
  185. if (p##gad == NULL) { \
  186. PromptInvalid("Handle is not a valid Gadget"); \
  187. SetError(E_INVALIDARG); \
  188. goto ErrorExit; \
  189. } \
  190. VALIDATE_GADGETCONTEXT(gad) \
  191. }
  192. #define VALIDATE_EVENTGADGET_NOCONTEXT(gad) \
  193. { \
  194. p##gad = ValidateBaseGadget(h##gad); \
  195. if (p##gad == NULL) { \
  196. PromptInvalid("Handle is not a valid Gadget"); \
  197. SetError(E_INVALIDARG); \
  198. goto ErrorExit; \
  199. } \
  200. }
  201. #define VALIDATE_VISUAL(gad) \
  202. { \
  203. p##gad = ValidateVisual(h##gad); \
  204. if (p##gad == NULL) { \
  205. PromptInvalid("Handle is not a valid Gadget"); \
  206. SetError(E_INVALIDARG); \
  207. goto ErrorExit; \
  208. } \
  209. VALIDATE_GADGETCONTEXT(gad) \
  210. }
  211. #define VALIDATE_ROOTGADGET(gad) \
  212. { \
  213. { \
  214. DuVisual * pgadTemp = ValidateVisual(h##gad); \
  215. if (pgadTemp == NULL) { \
  216. PromptInvalid("Handle is not a valid Gadget"); \
  217. SetError(E_INVALIDARG); \
  218. goto ErrorExit; \
  219. } \
  220. if (!pgadTemp->IsRoot()) { \
  221. goto ErrorExit; \
  222. } \
  223. VALIDATE_GADGETCONTEXT(gadTemp) \
  224. p##gad = (DuRootGadget *) pgadTemp; \
  225. } \
  226. }
  227. #define VALIDATE_VISUAL_OR_NULL(gad) \
  228. { \
  229. if (h##gad == NULL) { \
  230. p##gad = NULL; \
  231. } else { \
  232. p##gad = ValidateVisual(h##gad); \
  233. if (p##gad == NULL) { \
  234. PromptInvalid("Handle is not a valid Gadget"); \
  235. SetError(E_INVALIDARG); \
  236. goto ErrorExit; \
  237. } \
  238. VALIDATE_GADGETCONTEXT(gad) \
  239. } \
  240. }
  241. #define VALIDATE_TRANSITION(trx) \
  242. { \
  243. BaseObject * pbase##trx = BaseObject::ValidateHandle(h##trx); \
  244. p##trx = CastTransition(pbase##trx); \
  245. if (p##trx == NULL) { \
  246. PromptInvalid("Handle is not a valid Transition"); \
  247. SetError(E_INVALIDARG); \
  248. goto ErrorExit; \
  249. } \
  250. }
  251. #define VALIDATE_FLAGS(f, m) \
  252. if ((f & m) != f) { \
  253. PromptInvalid("Specified flags are invalid"); \
  254. SetError(E_INVALIDARG); \
  255. goto ErrorExit; \
  256. }
  257. #define VALIDATE_RANGE(i, a, b) \
  258. if (((i) < (a)) || ((i) > (b))) { \
  259. PromptInvalid("Value is outside expected range"); \
  260. SetError(E_INVALIDARG); \
  261. goto ErrorExit; \
  262. } \
  263. #define VALIDATE_CODE_PTR(p) \
  264. if ((p == NULL) || IsBadCode(p)) { \
  265. PromptInvalid("Bad code pointer: " STRINGIZE(p)); \
  266. SetError(E_INVALIDARG); \
  267. goto ErrorExit; \
  268. } \
  269. #define VALIDATE_CODE_PTR_OR_NULL(p) \
  270. if ((p != NULL) && IsBadCode((FARPROC) p)) { \
  271. PromptInvalid("Bad code pointer: " STRINGIZE(p)); \
  272. SetError(E_INVALIDARG); \
  273. goto ErrorExit; \
  274. } \
  275. #define VALIDATE_READ_PTR(p) \
  276. if ((p == NULL) || IsBadRead(p, sizeof(char *))) { \
  277. PromptInvalid("Bad read pointer: " STRINGIZE(p)); \
  278. SetError(E_INVALIDARG); \
  279. goto ErrorExit; \
  280. } \
  281. #define VALIDATE_READ_PTR_(p, b) \
  282. if ((p == NULL) || IsBadRead(p, b)) { \
  283. PromptInvalid("Bad read pointer: " STRINGIZE(p)); \
  284. SetError(E_INVALIDARG); \
  285. goto ErrorExit; \
  286. } \
  287. #define VALIDATE_READ_PTR_OR_NULL_(p, b) \
  288. if ((p != NULL) && IsBadRead(p, b)) { \
  289. PromptInvalid("Bad read pointer: " STRINGIZE(p)); \
  290. SetError(E_INVALIDARG); \
  291. goto ErrorExit; \
  292. } \
  293. #define VALIDATE_READ_STRUCT(p, s) \
  294. if ((p == NULL) || IsBadRead(p, sizeof(s))) { \
  295. PromptInvalid("Bad read pointer: " STRINGIZE(p)); \
  296. SetError(E_INVALIDARG); \
  297. goto ErrorExit; \
  298. } \
  299. if (p->cbSize != sizeof(s)) { \
  300. PromptInvalid("Structure is not expected size for " STRINGIZE(s)); \
  301. SetError(E_INVALIDARG); \
  302. goto ErrorExit; \
  303. }
  304. #define VALIDATE_WRITE_PTR(p) \
  305. if ((p == NULL) || IsBadWrite(p, sizeof(char *))) { \
  306. PromptInvalid("Bad write pointer: " STRINGIZE(p)); \
  307. SetError(E_INVALIDARG); \
  308. goto ErrorExit; \
  309. } \
  310. #define VALIDATE_WRITE_PTR_(p, b) \
  311. if ((p == NULL) || IsBadWrite(p, b)) { \
  312. PromptInvalid("Bad write pointer: " STRINGIZE(p)); \
  313. SetError(E_INVALIDARG); \
  314. goto ErrorExit; \
  315. } \
  316. #define VALIDATE_WRITE_PTR_OR_NULL_(p, b) \
  317. if ((p != NULL) && IsBadWrite(p, b)) { \
  318. PromptInvalid("Bad write pointer: " STRINGIZE(p)); \
  319. SetError(E_INVALIDARG); \
  320. goto ErrorExit; \
  321. } \
  322. #define VALIDATE_WRITE_STRUCT(p, s) \
  323. if ((p == NULL) || IsBadWrite(p, sizeof(s))) { \
  324. PromptInvalid("Bad write pointer: " STRINGIZE(p)); \
  325. SetError(E_INVALIDARG); \
  326. goto ErrorExit; \
  327. } \
  328. if (p->cbSize != sizeof(s)) { \
  329. PromptInvalid("Structure is not expected size for " STRINGIZE(s)); \
  330. SetError(E_INVALIDARG); \
  331. goto ErrorExit; \
  332. }
  333. #define VALIDATE_STRING_PTR(p, cch) \
  334. if ((p == NULL) || IsBadString(p, cch)) { \
  335. PromptInvalid("Bad string pointer: " STRINGIZE(p)); \
  336. SetError(E_INVALIDARG); \
  337. goto ErrorExit; \
  338. } \
  339. #define VALIDATE_STRINGA_PTR(p, cch) \
  340. if ((p == NULL) || IsBadStringA(p, cch)) { \
  341. PromptInvalid("Bad string pointer: " STRINGIZE(p)); \
  342. SetError(E_INVALIDARG); \
  343. goto ErrorExit; \
  344. } \
  345. #define VALIDATE_STRINGW_PTR(p, cch) \
  346. if ((p == NULL) || IsBadStringW(p, cch)) { \
  347. PromptInvalid("Bad string pointer: " STRINGIZE(p)); \
  348. SetError(E_INVALIDARG); \
  349. goto ErrorExit; \
  350. } \
  351. /***************************************************************************\
  352. *****************************************************************************
  353. *
  354. * DirectUser CORE API
  355. *
  356. * InitGadgets() initializes a DirectUser Context. The Context is valid in
  357. * the Thread until it is explicitely destroyed with ::DeleteHandle() or the
  358. * thread exits.
  359. *
  360. * NOTE: It is VERY important that the first time this function is called is
  361. * NOT in DllMain() because we need to initialize the SRT. DllMain()
  362. * serializes access across all threads, so we will deadlock. After the first
  363. * Context is successfully created, additional Contexts can be created inside
  364. * DllMain().
  365. *
  366. * <package name="Core"/>
  367. *
  368. *****************************************************************************
  369. \***************************************************************************/
  370. DUSER_API HDCONTEXT WINAPI
  371. InitGadgets(
  372. IN INITGADGET * pInit)
  373. {
  374. Context * pctxNew;
  375. HRESULT hr;
  376. BEGIN_RECV_NOCONTEXT(HDCONTEXT, NULL);
  377. VALIDATE_READ_STRUCT(pInit, INITGADGET);
  378. VALIDATE_RANGE(pInit->nThreadMode, IGTM_MIN, IGTM_MAX);
  379. VALIDATE_RANGE(pInit->nMsgMode, IGMM_MIN, IGMM_MAX);
  380. VALIDATE_RANGE(pInit->nPerfMode, IGPM_MIN, IGPM_MAX);
  381. hr = ResourceManager::InitContextNL(pInit, FALSE, &pctxNew);
  382. SET_RETURN(hr, (HDCONTEXT) GetHandle(pctxNew));
  383. END_RECV_NOCONTEXT();
  384. }
  385. /***************************************************************************\
  386. *
  387. * InitGadgetComponent (API)
  388. *
  389. * InitGadgetComponent() initializes optional DirectUser/Gadget components
  390. * that are not initialized by default. It is usually best to call this
  391. * function separately for each optional component to track individual
  392. * failures when initializing.
  393. *
  394. * <return type="BOOL"> Components were successfully initialized.</>
  395. * <see type="function"> CreateTransition</>
  396. * <see type="function"> UninitializeGadgetComponent</>
  397. *
  398. \***************************************************************************/
  399. DUSER_API BOOL WINAPI
  400. InitGadgetComponent(
  401. IN UINT nOptionalComponent) // Optional component ID
  402. {
  403. HRESULT hr;
  404. //
  405. // InitComponentNL() doesn't actually synchronize on a Context, but needs
  406. // a context to be initialized so that the threading model is determined.
  407. //
  408. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  409. VALIDATE_RANGE(nOptionalComponent, IGC_MIN, IGC_MAX);
  410. CHECK_MODIFY();
  411. hr = ResourceManager::InitComponentNL(nOptionalComponent);
  412. SET_RETURN(hr, TRUE);
  413. END_RECV();
  414. }
  415. /***************************************************************************\
  416. *
  417. * UninitGadgetComponent (API)
  418. *
  419. * UninitGadgetComponent() shuts down and cleans up optional DirectUser/Gadget
  420. * components that were previously initialized.
  421. *
  422. * <return type="BOOL"> Components were successfully uninitialized.</>
  423. * <see type="function"> InitGadgetComponent</>
  424. *
  425. \***************************************************************************/
  426. DUSER_API BOOL WINAPI
  427. UninitGadgetComponent(
  428. IN UINT nOptionalComponent) // Optional component
  429. {
  430. HRESULT hr;
  431. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  432. VALIDATE_RANGE(nOptionalComponent, IGC_MIN, IGC_MAX);
  433. CHECK_MODIFY();
  434. hr = ResourceManager::UninitComponentNL(nOptionalComponent);
  435. SET_RETURN(hr, TRUE);
  436. END_RECV();
  437. }
  438. /***************************************************************************\
  439. *
  440. * DeleteHandle (API)
  441. *
  442. * DeleteHandle() deletes any DirectUser handle by destroying the object and
  443. * cleaning up associated resources. After calling, the specified handle is
  444. * no longer valid. It may be used again later by another object.
  445. *
  446. * It is very important that only valid handles are given to ::DeleteHandle().
  447. * Passing invalid handles (including previously deleted handles) will crash
  448. * DirectUser.
  449. *
  450. * <return type="BOOL"> Object was successfully deleted.</>
  451. * <see type="function"> CreateGadget</>
  452. * <see type="function"> CreateTransition</>
  453. * <see type="function"> CreateAction</>
  454. *
  455. \***************************************************************************/
  456. DUSER_API BOOL WINAPI
  457. DeleteHandle(
  458. IN HANDLE h) // Handle to delete
  459. {
  460. BEGIN_RECV_NOLOCK(BOOL, FALSE);
  461. BaseObject * pobj = BaseObject::ValidateHandle(h);
  462. if (pobj != NULL) {
  463. if (pobj->GetHandleType() == htContext) {
  464. //
  465. // When destroying a Context, we can't lock it or it won't get
  466. // destroyed. This is okay since the ResourceManager serialize
  467. // the requests when it locks the thread-list.
  468. //
  469. pobj->xwDeleteHandle();
  470. retval = TRUE;
  471. } else {
  472. //
  473. // When destroying a normal object, lock the Context that the
  474. // object resides in.
  475. //
  476. ContextLock cl;
  477. if (cl.LockNL(ContextLock::edDefer, pctxThread)) {
  478. ObjectLock ol(pobj);
  479. CHECK_MODIFY();
  480. pobj->xwDeleteHandle();
  481. retval = TRUE;
  482. }
  483. }
  484. }
  485. //
  486. // NOTE: The object may not be deleted yet if there are any outstanding
  487. // locks against it. If it is a Gadget, it may be locked by one of the
  488. // message queues.
  489. //
  490. END_RECV_NOLOCK();
  491. }
  492. /***************************************************************************\
  493. *
  494. * DUserDeleteGadget (API)
  495. *
  496. * TODO: Document this API
  497. *
  498. \***************************************************************************/
  499. DUSER_API HRESULT WINAPI
  500. DUserDeleteGadget(
  501. IN DUser::Gadget * pg)
  502. {
  503. BEGIN_RECV_NOLOCK(HRESULT, E_INVALIDARG);
  504. MsgObject * pmo = MsgObject::CastMsgObject(pg);
  505. if (pmo == NULL) {
  506. PromptInvalid("Must specify a valid Gadget to delete");
  507. return E_INVALIDARG;
  508. }
  509. {
  510. //
  511. // When destroying a normal object, lock the Context that the
  512. // object resides in.
  513. //
  514. ContextLock cl;
  515. if (cl.LockNL(ContextLock::edDefer, pctxThread)) {
  516. ObjectLock ol(pmo);
  517. CHECK_MODIFY();
  518. pmo->xwDeleteHandle();
  519. retval = S_OK;
  520. }
  521. }
  522. //
  523. // NOTE: The object may not be deleted yet if there are any outstanding
  524. // locks against it. If it is a Gadget, it may be locked by one of the
  525. // message queues.
  526. //
  527. END_RECV_NOLOCK();
  528. }
  529. /***************************************************************************\
  530. *
  531. * IsStartDelete (API)
  532. *
  533. * TODO: Document this API
  534. *
  535. \***************************************************************************/
  536. DUSER_API BOOL WINAPI
  537. IsStartDelete(
  538. IN HANDLE hobj,
  539. IN BOOL * pfStarted)
  540. {
  541. BaseObject * pobj;
  542. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  543. VALIDATE_WRITE_PTR(pfStarted);
  544. VALIDATE_OBJECT(obj);
  545. *pfStarted = pobj->IsStartDelete();
  546. retval = TRUE;
  547. END_RECV();
  548. }
  549. /***************************************************************************\
  550. *
  551. * GetContext (API)
  552. *
  553. * TODO: Document this API
  554. *
  555. \***************************************************************************/
  556. DUSER_API HDCONTEXT WINAPI
  557. GetContext(
  558. IN HANDLE h)
  559. {
  560. BEGIN_RECV_NOCONTEXT(HDCONTEXT, NULL);
  561. // TODO: Totally rewrite this nonsense.
  562. {
  563. DuEventGadget * pgad;
  564. HGADGET hgad = (HGADGET) h;
  565. VALIDATE_EVENTGADGET_NOCONTEXT(gad);
  566. if (pgad != NULL) {
  567. retval = (HDCONTEXT) GetHandle(pgad->GetContext());
  568. }
  569. }
  570. END_RECV_NOCONTEXT();
  571. }
  572. /***************************************************************************\
  573. *
  574. * IsInsideContext (API)
  575. *
  576. * TODO: Document this API
  577. *
  578. \***************************************************************************/
  579. DUSER_API BOOL WINAPI
  580. IsInsideContext(HANDLE h)
  581. {
  582. BOOL fInside = FALSE;
  583. if ((h != NULL) && IsInitThread()) {
  584. __try
  585. {
  586. DuEventGadget * pgad = ValidateBaseGadget((HGADGET) h);
  587. if (pgad != NULL) {
  588. Context * pctxThread = GetContext();
  589. fInside = (pctxThread == pgad->GetContext());
  590. } else if (BaseObject::ValidateHandle(h) != NULL) {
  591. fInside = TRUE;
  592. }
  593. }
  594. __except(EXCEPTION_EXECUTE_HANDLER)
  595. {
  596. fInside = FALSE;
  597. }
  598. }
  599. return fInside;
  600. }
  601. /***************************************************************************\
  602. *
  603. * CreateGadget (API)
  604. *
  605. * CreateGadget() creates a new Gadget of a given type. Depending on the
  606. * specific flags, different Gadgets will actually be instantiated. Once a
  607. * Gadget of a specific type has been created, it can not be changed into a
  608. * different type without being deleted and recreated.
  609. *
  610. * <param name="nFlags">
  611. * Specifies both what type of Gadget to created and any creation-time
  612. * properties of that Gadget
  613. * <table item="Value" desc="Action">
  614. * GC_HWNDHOST Creates a top-level Gadget that can host a
  615. * GadgetTree inside the client area of a given
  616. * HWND. hParent must be a valid HWND.
  617. * GC_NCHOST Creates a top-level Gadget that can host a
  618. * GadgetTree inside the non-client area of a given
  619. * HWND. hParent must be a valid HWND.
  620. * GC_DXHOST Creates a top-level Gadget that can host a
  621. * GadgetTree inside a DXSurface. hParent must be
  622. * an LPCRECT specifying the area of the surface
  623. * the tree will be displayed on.
  624. * GC_COMPLEX Creates a sub-level Gadget that is optimized for
  625. * a complex subtree below it containing many other
  626. * Gadgets. More expensive than a Simple Gadget,
  627. * Complex Gadgets provide optimized region management
  628. * and are more equivalent to HWND's in both
  629. * functionality and design. hParent must specify a
  630. * valid HGADGET.
  631. * GC_SIMPLE Creates a sub-level Gadget that is optimized for
  632. * a simple subtree below it containing a few Gadgets.
  633. * Simple Gadgets are cheaper to create and often use
  634. * than Complex Gadgets if optimized region management
  635. * is not needed. hParent must specify a valid
  636. * HGADGET.
  637. * GC_DETACHED Creates a Gadget not integrated into a given Gadget
  638. * tree. Since they are separated from a tree,
  639. * operations must be explicitely forwarded to
  640. * Detached Gadgets during processing. hParent is
  641. * ignored.
  642. * GC_MESSAGE Creates a message-only Gadget that can receive and
  643. * send messages, but does not participate in any
  644. * visual or interactive manner. hParent is ignored.
  645. * </table>
  646. * </param>
  647. *
  648. * <return type="HGADGET"> Returns a handle to the newly created Gadget
  649. * or NULL if the creation failed.</>
  650. * <see type="function"> DeleteHandle</>
  651. *
  652. \***************************************************************************/
  653. DUSER_API HGADGET WINAPI
  654. CreateGadget(
  655. IN HANDLE hParent, // Handle to parent
  656. IN UINT nFlags, // Creation flags
  657. IN GADGETPROC pfnProc, // Pointer to the Gadget procedure
  658. IN void * pvGadgetData) // User data associated with this Gadget
  659. {
  660. BEGIN_RECV(HGADGET, NULL, ContextLock::edDefer);
  661. HRESULT hr;
  662. CREATE_INFO ci;
  663. ci.pfnProc = pfnProc;
  664. ci.pvData = pvGadgetData;
  665. switch (nFlags & GC_TYPE)
  666. {
  667. case GC_HWNDHOST:
  668. {
  669. HWND hwndContainer = (HWND) hParent;
  670. VALIDATE_HWND(wndContainer);
  671. DuRootGadget * pgadRoot;
  672. hr = GdCreateHwndRootGadget(hwndContainer, &ci, &pgadRoot);
  673. SET_RETURN(hr, (HGADGET) GetHandle(pgadRoot));
  674. }
  675. break;
  676. case GC_NCHOST:
  677. {
  678. HWND hwndContainer = (HWND) hParent;
  679. VALIDATE_HWND(wndContainer);
  680. DuRootGadget * pgadRoot;
  681. hr = GdCreateNcRootGadget(hwndContainer, &ci, &pgadRoot);
  682. SET_RETURN(hr, (HGADGET) GetHandle(pgadRoot));
  683. }
  684. break;
  685. case GC_DXHOST:
  686. {
  687. const RECT * prcContainerRect = (const RECT *) hParent;
  688. VALIDATE_READ_PTR_(prcContainerRect, sizeof(RECT));
  689. DuRootGadget * pgadRoot;
  690. hr = GdCreateDxRootGadget(prcContainerRect, &ci, &pgadRoot);
  691. SET_RETURN(hr, (HGADGET) GetHandle(pgadRoot));
  692. }
  693. break;
  694. case GC_COMPLEX:
  695. PromptInvalid("Complex Gadgets are not yet implemented");
  696. SetError(E_NOTIMPL);
  697. break;
  698. case GC_SIMPLE:
  699. {
  700. DuVisual * pgadParent;
  701. HGADGET hgadParent = (HGADGET) hParent;
  702. VALIDATE_VISUAL_OR_NULL(gadParent);
  703. if (pgadParent == NULL) {
  704. pgadParent = GetCoreSC()->pconPark->GetRoot();
  705. if (pgadParent == NULL) {
  706. //
  707. // The Parking Gadget has already been destroyed, so can not
  708. // create a new child.
  709. //
  710. SetError(E_INVALIDARG);
  711. goto ErrorExit;
  712. }
  713. }
  714. DuVisual * pgadChild;
  715. hr = pgadParent->AddChild(&ci, &pgadChild);
  716. SET_RETURN(hr, (HGADGET) GetHandle(pgadChild));
  717. }
  718. break;
  719. case GC_DETACHED:
  720. PromptInvalid("Detached Gadgets are not yet implemented");
  721. SetError(E_NOTIMPL);
  722. break;
  723. case GC_MESSAGE:
  724. {
  725. VALIDATE_VALUE(hParent, NULL);
  726. VALIDATE_CODE_PTR(pfnProc); // MsgGadget's must have a GadgetProc
  727. DuListener * pgadNew;
  728. hr = DuListener::Build(&ci, &pgadNew);
  729. SET_RETURN(hr, (HGADGET) GetHandle(pgadNew));
  730. }
  731. break;
  732. default:
  733. PromptInvalid("Invalid Gadget type");
  734. SetError(E_INVALIDARG);
  735. }
  736. END_RECV();
  737. }
  738. /***************************************************************************\
  739. *
  740. * GetGadgetFocus (API)
  741. *
  742. * GetGadgetFocus() returns the Gadget with current keyboard focus or NULL
  743. * if no Gadget currently has focus.
  744. *
  745. * <return type="HGADGET"> Gadget with keyboard focus.</>
  746. * <see type="function"> SetGadgetFocus</>
  747. * <see type="message"> GM_CHANGESTATE</>
  748. *
  749. \***************************************************************************/
  750. DUSER_API HGADGET WINAPI
  751. GetGadgetFocus()
  752. {
  753. BEGIN_RECV(HGADGET, NULL, ContextLock::edNone);
  754. retval = (HGADGET) GetHandle(DuRootGadget::GetFocus());
  755. END_RECV();
  756. }
  757. /***************************************************************************\
  758. *
  759. * SetGadgetFocus (API)
  760. *
  761. * SetGadgetFocus() moves keyboard focus to the specified Gadget. Both the
  762. * current Gadget with keyboard focus and the Gadget being specified will be
  763. * sent a GM_CHANGESTATE message with nCode=GSTATE_KEYBOARDFOCUS notifying of
  764. * the focus change.
  765. *
  766. * <return type="BOOL"> Focus was successfully moved.</>
  767. * <see type="function"> GetGadgetFocus</>
  768. * <see type="message"> GM_CHANGESTATE</>
  769. *
  770. \***************************************************************************/
  771. DUSER_API BOOL WINAPI
  772. SetGadgetFocus(
  773. IN HGADGET hgadFocus) // Gadget to receive focus.
  774. {
  775. DuVisual * pgadFocus;
  776. DuRootGadget * pgadRoot;
  777. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  778. VALIDATE_VISUAL(gadFocus);
  779. CHECK_MODIFY();
  780. //
  781. // TODO: Do we need to only allow the app to change focus if on the same
  782. // thread? USER does this.
  783. //
  784. pgadRoot = pgadFocus->GetRoot();
  785. if (pgadRoot != NULL) {
  786. retval = pgadRoot->xdSetKeyboardFocus(pgadFocus);
  787. }
  788. END_RECV();
  789. }
  790. /***************************************************************************\
  791. *
  792. * IsGadgetParentChainStyle (API)
  793. *
  794. * IsGadgetParentChainStyle() checks if a Gadget parent change has the
  795. * specified style bits set.
  796. *
  797. * <return type="BOOL"> Gadget was successfully checked.</>
  798. * <see type="function"> GetGadgetStyle</>
  799. * <see type="function"> SetGadgetStyle</>
  800. *
  801. \***************************************************************************/
  802. DUSER_API BOOL WINAPI
  803. IsGadgetParentChainStyle(
  804. IN HGADGET hgad, // Gadget to check visibility
  805. IN UINT nStyle, // Style bits to check
  806. OUT BOOL * pfChain, // Chain state
  807. IN UINT nFlags) // Optional flags
  808. {
  809. DuVisual * pgad;
  810. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  811. VALIDATE_VISUAL(gad);
  812. VALIDATE_VALUE(nFlags, 0);
  813. VALIDATE_FLAGS(nStyle, GS_VALID);
  814. VALIDATE_WRITE_PTR_(pfChain, sizeof(BOOL));
  815. CHECK_MODIFY();
  816. *pfChain = pgad->IsParentChainStyle(nStyle);
  817. retval = TRUE;
  818. END_RECV();
  819. }
  820. /***************************************************************************\
  821. *
  822. * SetGadgetFillI (API)
  823. *
  824. * SetGadgetFillI() specifies an optional brush to fill the Gadget's
  825. * background with when drawing. The background will be filled before the
  826. * Gadget is given the GM_PAINT message to draw.
  827. *
  828. * <return type="BOOL"> Fill was successfully set.</>
  829. * <see type="function"> UtilDrawBlendRect</>
  830. * <see type="message"> GM_PAINT</>
  831. *
  832. \***************************************************************************/
  833. DUSER_API BOOL WINAPI
  834. SetGadgetFillI(
  835. IN HGADGET hgadChange, // Gadget to change
  836. IN HBRUSH hbrFill, // Brush to fill with or NULL to remove
  837. IN BYTE bAlpha, // Alpha level to apply brush
  838. IN int w, // Optional width of brush when
  839. // alpha-blending or 0 for default
  840. IN int h) // Optional height of brush when
  841. // alpha-blending or 0 for default
  842. {
  843. DuVisual * pgadChange;
  844. HRESULT hr;
  845. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  846. VALIDATE_VISUAL(gadChange);
  847. CHECK_MODIFY();
  848. hr = pgadChange->SetFill(hbrFill, bAlpha, w, h);
  849. SET_RETURN(hr, TRUE);
  850. END_RECV();
  851. }
  852. /***************************************************************************\
  853. *
  854. * SetGadgetFillF (API)
  855. *
  856. * SetGadgetFillF() specifies an optional brush to fill the Gadget's
  857. * background with when drawing. The background will be filled before the
  858. * Gadget is given the GM_PAINT message to draw.
  859. *
  860. * <return type="BOOL"> Fill was successfully set.</>
  861. * <see type="function"> UtilDrawBlendRect</>
  862. * <see type="message"> GM_PAINT</>
  863. *
  864. \***************************************************************************/
  865. DUSER_API BOOL WINAPI
  866. SetGadgetFillF(
  867. IN HGADGET hgadChange, // Gadget to change
  868. IN Gdiplus::Brush * pgpbr) // Brush to fill with or NULL to remove
  869. {
  870. DuVisual * pgadChange;
  871. HRESULT hr;
  872. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  873. VALIDATE_VISUAL(gadChange);
  874. CHECK_MODIFY();
  875. hr = pgadChange->SetFill(pgpbr);
  876. SET_RETURN(hr, TRUE);
  877. END_RECV();
  878. }
  879. /***************************************************************************\
  880. *
  881. * GetGadgetScale (API)
  882. *
  883. * GetGadgetScale() returns the Gadget's scaling factor. If the Gadget is
  884. * not scaled, the factors will be X=1.0, Y=1.0.
  885. *
  886. * <return type="BOOL"> Successfully returned scaling factor</>
  887. * <see type="function"> SetGadgetScale</>
  888. * <see type="function"> GetGadgetRotation</>
  889. * <see type="function"> SetGadgetRotation</>
  890. * <see type="function"> GetGadgetRect</>
  891. * <see type="function"> SetGadgetRect</>
  892. *
  893. \***************************************************************************/
  894. DUSER_API BOOL WINAPI
  895. GetGadgetScale(
  896. IN HGADGET hgad, // Gadget to check
  897. OUT float * pflX, // Horizontal scaling factor
  898. OUT float * pflY) // Vertical scaling factor
  899. {
  900. DuVisual * pgad;
  901. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  902. VALIDATE_VISUAL(gad);
  903. VALIDATE_WRITE_PTR_(pflX, sizeof(float));
  904. VALIDATE_WRITE_PTR_(pflY, sizeof(float));
  905. pgad->GetScale(pflX, pflY);
  906. retval = TRUE;
  907. END_RECV();
  908. }
  909. /***************************************************************************\
  910. *
  911. * SetGadgetScale (API)
  912. *
  913. * SetGadgetScale() changes the specified Gadget's scaling factor. Scaling
  914. * is determined from the upper-left corner of the Gadget and is applied
  915. * dynamically during painting and hit-testing. The Gadget's logical
  916. * rectangle set by SetGadgetRect() does not change.
  917. *
  918. * When scaling is applied to a Gadget, the entire subtree of that Gadget is
  919. * scaled. To remove any scaling factor, use X=1.0, Y=1.0.
  920. *
  921. * <return type="BOOL"> Successfully changed scaling factor</>
  922. * <see type="function"> GetGadgetScale</>
  923. * <see type="function"> GetGadgetRotation</>
  924. * <see type="function"> SetGadgetRotation</>
  925. * <see type="function"> GetGadgetRect</>
  926. * <see type="function"> SetGadgetRect</>
  927. *
  928. \***************************************************************************/
  929. DUSER_API BOOL WINAPI
  930. SetGadgetScale(
  931. IN HGADGET hgadChange, // Gadget to change
  932. IN float flX, // New horizontal scaling factor
  933. IN float flY) // New vertical scaling factor
  934. {
  935. DuVisual * pgadChange;
  936. HRESULT hr;
  937. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  938. VALIDATE_VISUAL(gadChange);
  939. CHECK_MODIFY();
  940. hr = pgadChange->xdSetScale(flX, flY);
  941. SET_RETURN(hr, TRUE);
  942. END_RECV();
  943. }
  944. /***************************************************************************\
  945. *
  946. * GetGadgetRotation (API)
  947. *
  948. * GetGadgetRotation() returns the Gadget's rotation factor in radians. If
  949. * a Gadget is not rotated, the factor will be 0.0.
  950. *
  951. * <return type="BOOL"> Successfully returned rotation factor</>
  952. * <see type="function"> GetGadgetScale</>
  953. * <see type="function"> SetGadgetScale</>
  954. * <see type="function"> SetGadgetRotation</>
  955. * <see type="function"> GetGadgetRect</>
  956. * <see type="function"> SetGadgetRect</>
  957. *
  958. \***************************************************************************/
  959. DUSER_API BOOL WINAPI
  960. GetGadgetRotation(
  961. IN HGADGET hgad, // Gadget to check
  962. OUT float * pflRotationRad) // Rotation factor in radians
  963. {
  964. DuVisual * pgad;
  965. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  966. VALIDATE_VISUAL(gad);
  967. VALIDATE_WRITE_PTR_(pflRotationRad, sizeof(float));
  968. *pflRotationRad = pgad->GetRotation();
  969. retval = TRUE;
  970. END_RECV();
  971. }
  972. /***************************************************************************\
  973. *
  974. * SetGadgetRotation (API)
  975. *
  976. * SetGadgetRotation() changes the specified Gadget's rotation factor in
  977. * radians. Scaling is determined from the upper-left corner of the Gadget
  978. * and is applied dynamically during painting and hit-testing. The Gadget's
  979. * logical rectangle set by SetGadgetRect() does not change.
  980. *
  981. * When rotation is applied to a Gadget, the entire subtree of that Gadget is
  982. * rotated. To remove any rotation factor, use 0.0.
  983. *
  984. * <return type="BOOL"> Successfully changed scaling factor</>
  985. * <see type="function"> GetGadgetScale</>
  986. * <see type="function"> SetGadgetScale</>
  987. * <see type="function"> GetGadgetRotation</>
  988. * <see type="function"> GetGadgetRect</>
  989. * <see type="function"> SetGadgetRect</>
  990. *
  991. \***************************************************************************/
  992. DUSER_API BOOL WINAPI
  993. SetGadgetRotation(
  994. IN HGADGET hgadChange, // Gadget to change
  995. IN float flRotationRad) // New rotation factor in radians
  996. {
  997. DuVisual * pgadChange;
  998. HRESULT hr;
  999. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1000. VALIDATE_VISUAL(gadChange);
  1001. CHECK_MODIFY();
  1002. hr = pgadChange->xdSetRotation(flRotationRad);
  1003. SET_RETURN(hr, TRUE);
  1004. END_RECV();
  1005. }
  1006. //------------------------------------------------------------------------------
  1007. DUSER_API BOOL WINAPI
  1008. GetGadgetCenterPoint(HGADGET hgad, float * pflX, float * pflY)
  1009. {
  1010. DuVisual * pgad;
  1011. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  1012. VALIDATE_VISUAL(gad);
  1013. VALIDATE_WRITE_PTR_(pflX, sizeof(float));
  1014. VALIDATE_WRITE_PTR_(pflY, sizeof(float));
  1015. pgad->GetCenterPoint(pflX, pflY);
  1016. retval = TRUE;
  1017. END_RECV();
  1018. }
  1019. //------------------------------------------------------------------------------
  1020. DUSER_API BOOL WINAPI
  1021. SetGadgetCenterPoint(HGADGET hgadChange, float flX, float flY)
  1022. {
  1023. DuVisual * pgadChange;
  1024. HRESULT hr;
  1025. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1026. VALIDATE_VISUAL(gadChange);
  1027. CHECK_MODIFY();
  1028. hr = pgadChange->xdSetCenterPoint(flX, flY);
  1029. SET_RETURN(hr, TRUE);
  1030. END_RECV();
  1031. }
  1032. //------------------------------------------------------------------------------
  1033. DUSER_API BOOL WINAPI
  1034. GetGadgetBufferInfo(
  1035. IN HGADGET hgad, // Gadget to check
  1036. OUT BUFFER_INFO * pbi) // Buffer information
  1037. {
  1038. DuVisual * pgad;
  1039. HRESULT hr;
  1040. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  1041. VALIDATE_VISUAL(gad);
  1042. VALIDATE_WRITE_STRUCT(pbi, BUFFER_INFO);
  1043. VALIDATE_FLAGS(pbi->nMask, GBIM_VALID);
  1044. if (!pgad->IsBuffered()) {
  1045. PromptInvalid("Gadget is not GS_BUFFERED");
  1046. SetError(DU_E_NOTBUFFERED);
  1047. goto ErrorExit;
  1048. }
  1049. hr = pgad->GetBufferInfo(pbi);
  1050. SET_RETURN(hr, TRUE);
  1051. END_RECV();
  1052. }
  1053. //------------------------------------------------------------------------------
  1054. DUSER_API BOOL WINAPI
  1055. SetGadgetBufferInfo(
  1056. IN HGADGET hgadChange, // Gadget to change
  1057. IN const BUFFER_INFO * pbi) // Buffer information
  1058. {
  1059. DuVisual * pgadChange;
  1060. HRESULT hr;
  1061. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1062. VALIDATE_VISUAL(gadChange);
  1063. VALIDATE_READ_STRUCT(pbi, BUFFER_INFO);
  1064. VALIDATE_FLAGS(pbi->nMask, GBIM_VALID);
  1065. if (!pgadChange->IsBuffered()) {
  1066. PromptInvalid("Gadget is not GS_BUFFERED");
  1067. SetError(DU_E_NOTBUFFERED);
  1068. goto ErrorExit;
  1069. }
  1070. hr = pgadChange->SetBufferInfo(pbi);
  1071. SET_RETURN(hr, TRUE);
  1072. END_RECV();
  1073. }
  1074. //------------------------------------------------------------------------------
  1075. DUSER_API BOOL WINAPI
  1076. GetGadgetRgn(
  1077. IN HGADGET hgad, // Gadget to get region of
  1078. IN UINT nRgnType, // Type of region
  1079. OUT HRGN hrgn, // Specified region
  1080. IN UINT nFlags) // Modifying flags
  1081. {
  1082. DuVisual * pgad;
  1083. HRESULT hr;
  1084. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  1085. VALIDATE_VISUAL(gad);
  1086. VALIDATE_RANGE(nRgnType, GRT_MIN, GRT_MAX);
  1087. VALIDATE_REGION(rgn);
  1088. hr = pgad->GetRgn(nRgnType, hrgn, nFlags);
  1089. SET_RETURN(hr, TRUE);
  1090. END_RECV();
  1091. }
  1092. //------------------------------------------------------------------------------
  1093. DUSER_API BOOL WINAPI
  1094. GetGadgetRootInfo(
  1095. IN HGADGET hgadRoot, // RootGadget to modify
  1096. IN ROOT_INFO * pri) // Information
  1097. {
  1098. DuRootGadget * pgadRoot;
  1099. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  1100. VALIDATE_ROOTGADGET(gadRoot);
  1101. VALIDATE_WRITE_STRUCT(pri, ROOT_INFO);
  1102. VALIDATE_FLAGS(pri->nMask, GRIM_VALID);
  1103. pgadRoot->GetInfo(pri);
  1104. retval = TRUE;
  1105. END_RECV();
  1106. }
  1107. //------------------------------------------------------------------------------
  1108. DUSER_API BOOL WINAPI
  1109. SetGadgetRootInfo(
  1110. IN HGADGET hgadRoot, // RootGadget to modify
  1111. IN const ROOT_INFO * pri) // Information
  1112. {
  1113. DuRootGadget * pgadRoot;
  1114. HRESULT hr;
  1115. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1116. VALIDATE_ROOTGADGET(gadRoot);
  1117. VALIDATE_READ_STRUCT(pri, ROOT_INFO);
  1118. VALIDATE_FLAGS(pri->nMask, GRIM_VALID);
  1119. VALIDATE_FLAGS(pri->nOptions, GRIO_VALID);
  1120. VALIDATE_RANGE(pri->nSurface, GSURFACE_MIN, GSURFACE_MAX);
  1121. VALIDATE_RANGE(pri->nDropTarget, GRIDT_MIN, GRIDT_MAX);
  1122. hr = pgadRoot->SetInfo(pri);
  1123. SET_RETURN(hr, TRUE);
  1124. END_RECV();
  1125. }
  1126. //------------------------------------------------------------------------------
  1127. DUSER_API HRESULT WINAPI
  1128. DUserSendMethod(
  1129. IN MethodMsg * pmsg) // Message to send
  1130. {
  1131. Context * pctxGad, * pctxSend;
  1132. HGADGET hgadMsg;
  1133. MsgObject * pmo;
  1134. UINT nResult;
  1135. HRESULT hr;
  1136. UINT hm;
  1137. //
  1138. // Validation for DUserSendMethod() is a little unusual because the
  1139. // caller doesn't need to be in the same Context as the Gadget itself. This
  1140. // means we need to get the Context from the Gadget and not use TLS.
  1141. //
  1142. // The Caller must be initialized, but we WON'T take the context-lock.
  1143. // TODO: Investigate whether we should actually do this because it may
  1144. // allow us to take off the lock on the DUserHeap.
  1145. //
  1146. // NOTE: This code has been HIGHLY optimized so that in-context Send
  1147. // messages will be as fast as possible.
  1148. //
  1149. nResult = DU_S_NOTHANDLED;
  1150. if ((pmsg == NULL) || ((hgadMsg = pmsg->hgadMsg) == NULL) || (pmsg->nMsg >= GM_EVENT)) {
  1151. PromptInvalid("Invalid parameters to SendGadgetMethod()");
  1152. hr = E_INVALIDARG;
  1153. goto Exit;
  1154. }
  1155. pmo = reinterpret_cast<MsgObject *>(hgadMsg);
  1156. hm = pmo->GetHandleMask();
  1157. if (!TestFlag(hm, hmMsgObject)) {
  1158. PromptInvalid("Object is not a valid Gadget");
  1159. hr = E_INVALIDARG;
  1160. goto Exit;
  1161. }
  1162. if (TestFlag(hm, hmEventGadget)) {
  1163. DuEventGadget * pgadMsg = static_cast<DuEventGadget *>(pmo);
  1164. pctxSend = RawGetContext();
  1165. pctxGad = pgadMsg->GetContext();
  1166. AssertMsg(pctxGad != NULL, "Fully created DuEventGadget must have a Context");
  1167. if (pctxSend->IsOrphanedNL() || pctxGad->IsOrphanedNL()) {
  1168. PromptInvalid("Illegally using an orphaned Context");
  1169. hr = E_INVALIDARG;
  1170. goto Exit;
  1171. }
  1172. if (pctxSend == pctxGad) {
  1173. pmo->InvokeMethod(pmsg);
  1174. hr = S_OK;
  1175. goto Exit;
  1176. } else {
  1177. hr = GetCoreSC(pctxSend)->xwSendMethodNL(GetCoreSC(pctxGad), pmsg, pmo);
  1178. }
  1179. } else {
  1180. //
  1181. // For non-BaseGadgets, use the current context. This means that we can
  1182. // invoke directly.
  1183. //
  1184. pmo->InvokeMethod(pmsg);
  1185. hr = S_OK;
  1186. }
  1187. Exit:
  1188. return hr;
  1189. }
  1190. /***************************************************************************\
  1191. *
  1192. * SendGadgetEvent (API)
  1193. *
  1194. * SendGadgetEvent() sends a message to the specified Gadget. The function
  1195. * calls the Gadget procedure and does not return until the Gadget has
  1196. * processed the message.
  1197. *
  1198. * <param name="pmsg">
  1199. * Several members of the GMSG must be previously filled to correctly send
  1200. * the message to the specified Gadget.
  1201. * <table item="Field" desc="Description">
  1202. * cbSize Size of the message being sent in bytes.
  1203. * nMsg ID of the message.
  1204. * hgadMsg Gadget that the message is being sent to.
  1205. * result Default result value.
  1206. * </table>
  1207. * </param>
  1208. *
  1209. * <param nane="nFlags">
  1210. * Specifies optional flags to modify how the message is sent to the Gadget.
  1211. * <table item="Value" desc="Action">
  1212. * SGM_BUBBLE The message will be fully routed and bubbled inside
  1213. * the Gadget Tree. If this flag is not specified, the
  1214. * message will only be sent directly to the Gadget and
  1215. * any attached Message Handlers.
  1216. * </table>
  1217. * </param>
  1218. *
  1219. * <return type="UINT">
  1220. * Return value specifying how message was handled:
  1221. * <table item="Value" desc="Action">
  1222. * GPR_COMPLETE The message was completely handled by a Gadget
  1223. * in the processing loop.
  1224. * GPR_PARTIAL The message was partially handled by one or
  1225. * more Gadget in the processing loop, but was never
  1226. * completely handled.
  1227. * GPR_NOTHANDLED The message was never handled by any Gadgets in
  1228. * the processing loop.
  1229. * </table>
  1230. * </return>
  1231. *
  1232. * <see type="function"> RegisterGadgetMessage</>
  1233. * <see type="function"> RegisterGadgetMessageString</>
  1234. * <see type="function"> UnregisterGadgetMessage</>
  1235. * <see type="function"> UnregisterGadgetMessageString</>
  1236. * <see type="function"> AddGadgetMessageHandler</>
  1237. * <see type="function"> RemoveGadgetMessageHandler</>
  1238. * <see type="struct"> GMSG</>
  1239. * <see type="article"> GadgetMessaging</>
  1240. *
  1241. \***************************************************************************/
  1242. DUSER_API HRESULT WINAPI
  1243. DUserSendEvent(
  1244. IN EventMsg * pmsg, // Message to send
  1245. IN UINT nFlags) // Optional flags to modifying sending
  1246. {
  1247. Context * pctxGad, * pctxSend;
  1248. HGADGET hgadMsg;
  1249. DuEventGadget * pgad;
  1250. HRESULT nResult;
  1251. UINT hm;
  1252. //
  1253. // Validation for SendGadgetEvent() is a little unusual because the
  1254. // caller doesn't need to be in the same Context as the Gadget itself. This
  1255. // means we need to get the Context from the Gadget and not use TLS.
  1256. //
  1257. // The Caller must be initialized, but we WON'T take the context-lock.
  1258. // TODO: Investigate whether we should actually do this because it may
  1259. // allow us to take off the lock on the DUserHeap.
  1260. //
  1261. // NOTE: This code has been HIGHLY optimized so that in-context Send
  1262. // messages will be as fast as possible.
  1263. //
  1264. nResult = E_INVALIDARG;
  1265. if ((pmsg == NULL) || ((hgadMsg = pmsg->hgadMsg) == NULL) || (pmsg->nMsg < GM_EVENT)) {
  1266. PromptInvalid("Invalid parameters to SendGadgetEvent()");
  1267. goto Error;
  1268. }
  1269. pgad = reinterpret_cast<DuEventGadget *>(hgadMsg);
  1270. hm = pgad->GetHandleMask();
  1271. if (!TestFlag(hm, hmEventGadget)) {
  1272. PromptInvalid("Object is not a valid BaseGadget");
  1273. goto Error;
  1274. }
  1275. pctxSend = RawGetContext();
  1276. pctxGad = pgad->GetContext();
  1277. AssertMsg(pctxGad != NULL, "Fully created DuEventGadget must have a Context");
  1278. if (pctxSend->IsOrphanedNL() || pctxGad->IsOrphanedNL()) {
  1279. PromptInvalid("Illegally using an orphaned Context");
  1280. goto Error;
  1281. }
  1282. if (pctxSend == pctxGad) {
  1283. const GPCB & cb = pgad->GetCallback();
  1284. if (TestFlag(nFlags, SGM_FULL) && TestFlag(hm, hmVisual)) {
  1285. nResult = cb.xwInvokeFull((const DuVisual *) pgad, pmsg, 0);
  1286. } else {
  1287. nResult = cb.xwInvokeDirect(pgad, pmsg, 0);
  1288. }
  1289. } else {
  1290. nResult = GetCoreSC(pctxSend)->xwSendEventNL(GetCoreSC(pctxGad), pmsg, pgad, nFlags);
  1291. }
  1292. return nResult;
  1293. Error:
  1294. return E_INVALIDARG;
  1295. }
  1296. //------------------------------------------------------------------------------
  1297. DUSER_API HRESULT WINAPI
  1298. DUserPostMethod(
  1299. IN MethodMsg * pmsg) // Message to post
  1300. {
  1301. Context * pctxGad, * pctxSend;
  1302. HGADGET hgadMsg;
  1303. MsgObject * pmo;
  1304. UINT nResult;
  1305. HRESULT hr;
  1306. UINT hm;
  1307. //
  1308. // Validation for PostGadgetEvent() is a little unusual because the
  1309. // caller doesn't need to be in the same Context as the Gadget itself. This
  1310. // means we need to get the Context from the Gadget and not use TLS.
  1311. //
  1312. nResult = DU_S_NOTHANDLED;
  1313. if ((pmsg == NULL) || ((hgadMsg = pmsg->hgadMsg) == NULL) || (pmsg->nMsg >= GM_EVENT)) {
  1314. PromptInvalid("Invalid parameters to DUserPostMethod()");
  1315. hr = E_INVALIDARG;
  1316. goto Exit;
  1317. }
  1318. pmo = reinterpret_cast<MsgObject *>(hgadMsg);
  1319. hm = pmo->GetHandleMask();
  1320. if (!TestFlag(hm, hmMsgObject)) {
  1321. PromptInvalid("Object is not a valid Gadget");
  1322. hr = E_INVALIDARG;
  1323. goto Exit;
  1324. }
  1325. if (TestFlag(hm, hmEventGadget)) {
  1326. DuEventGadget * pgad = static_cast<DuEventGadget *>(pmo);
  1327. pctxSend = RawGetContext();
  1328. pctxGad = pgad->GetContext();
  1329. AssertMsg(pctxGad != NULL, "Fully created Gadgets must have a Context");
  1330. } else {
  1331. //
  1332. // For non-BaseGadgets, use the current context.
  1333. //
  1334. pctxSend = pctxGad = GetContext();
  1335. if (pctxGad == NULL) {
  1336. PromptInvalid("Must initialize Context before using thread");
  1337. hr = DU_E_NOCONTEXT;
  1338. goto Exit;
  1339. }
  1340. }
  1341. if (pctxSend->IsOrphanedNL() || pctxGad->IsOrphanedNL()) {
  1342. PromptInvalid("Illegally using an orphaned Context");
  1343. hr = E_INVALIDARG;
  1344. goto Exit;
  1345. }
  1346. hr = GetCoreSC(pctxSend)->PostMethodNL(GetCoreSC(pctxGad), pmsg, pmo);
  1347. Exit:
  1348. return hr;
  1349. }
  1350. /***************************************************************************\
  1351. *
  1352. * DUserPostEvent (API)
  1353. *
  1354. * DUserPostEvent() posts a message to the specified Gadget. The function
  1355. * calls the Gadget procedure and returns after the message has bee successfully
  1356. * posted to the owning messsage queue.
  1357. *
  1358. * <param name="pmsg">
  1359. * Several members of the GMSG must be previously filled to correctly send
  1360. * the message to the specified Gadget.
  1361. * <table item="Field" desc="Description">
  1362. * cbSize Size of the message being sent in bytes.
  1363. * nMsg ID of the message.
  1364. * hgadMsg Gadget that the message is being sent to.
  1365. * result Default result value.
  1366. * </table>
  1367. * </param>
  1368. *
  1369. * <param nane="nFlags">
  1370. * Specifies optional flags to modify how the message is sent to the Gadget.
  1371. * <table item="Value" desc="Action">
  1372. * SGM_BUBBLE The message will be fully routed and bubbled inside
  1373. * the Gadget Tree. If this flag is not specified, the
  1374. * message will only be sent directly to the Gadget and
  1375. * any attached Message Handlers.
  1376. * </table>
  1377. * </param>
  1378. *
  1379. * <return type="BOOL">
  1380. * Message was successfully posted to the destination Gadget's queue.
  1381. * </return>
  1382. *
  1383. * <see type="function"> SendGadgetEvent</>
  1384. * <see type="function"> RegisterGadgetMessage</>
  1385. * <see type="function"> RegisterGadgetMessageString</>
  1386. * <see type="function"> UnregisterGadgetMessage</>
  1387. * <see type="function"> UnregisterGadgetMessageString</>
  1388. * <see type="function"> AddGadgetMessageHandler</>
  1389. * <see type="function"> RemoveGadgetMessageHandler</>
  1390. * <see type="struct"> GMSG</>
  1391. * <see type="article"> GadgetMessaging</>
  1392. *
  1393. \***************************************************************************/
  1394. DUSER_API HRESULT WINAPI
  1395. DUserPostEvent(
  1396. IN EventMsg * pmsg, // Message to post
  1397. IN UINT nFlags) // Optional flags modifiying posting
  1398. {
  1399. Context * pctxGad;
  1400. HGADGET hgad;
  1401. DuEventGadget * pgad;
  1402. HRESULT hr;
  1403. //
  1404. // Validation for PostGadgetEvent() is a little unusual because the
  1405. // caller doesn't need to be in the same Context as the Gadget itself. This
  1406. // means we need to get the Context from the Gadget and not use TLS.
  1407. //
  1408. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1409. VALIDATE_READ_PTR_(pmsg, pmsg->cbSize);
  1410. VALIDATE_FLAGS(nFlags, SGM_VALID);
  1411. if (pmsg->nMsg < GM_EVENT) {
  1412. PromptInvalid("Can not post private messages");
  1413. SetError(E_INVALIDARG);
  1414. goto ErrorExit;
  1415. }
  1416. if (!IsInitContext()) {
  1417. PromptInvalid("Must initialize Context before using thread");
  1418. SetError(DU_E_NOCONTEXT);
  1419. goto ErrorExit;
  1420. }
  1421. hgad = pmsg->hgadMsg;
  1422. VALIDATE_EVENTGADGET_NOCONTEXT(gad);
  1423. pctxGad = pgad->GetContext();
  1424. if (pctxGad->IsOrphanedNL()) {
  1425. PromptInvalid("Illegally using an orphaned Context");
  1426. goto ErrorExit;
  1427. }
  1428. hr = GetCoreSC()->PostEventNL(GetCoreSC(pctxGad), pmsg, pgad, nFlags);
  1429. SET_RETURN(hr, TRUE);
  1430. END_RECV_NOCONTEXT();
  1431. }
  1432. //------------------------------------------------------------------------------
  1433. DUSER_API BOOL WINAPI
  1434. FireGadgetMessages(
  1435. IN FGM_INFO * rgFGM, // Collection of messsages to fire
  1436. IN int cMsgs, // Number of messages
  1437. IN UINT idQueue) // Queue to send messages
  1438. {
  1439. Context * pctxGad, * pctxCheck;
  1440. HGADGET hgad;
  1441. DuEventGadget * pgad;
  1442. HRESULT hr;
  1443. int idx;
  1444. //
  1445. // Validation for FireGadgetMessages() is a little unusual because the
  1446. // caller doesn't need to be in the same Context as the Gadget itself. This
  1447. // means we need to get the Context from the Gadget and not use TLS.
  1448. //
  1449. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1450. if (cMsgs <= 0) {
  1451. PromptInvalid("Must specify a valid number of messages to process.");
  1452. SetError(E_INVALIDARG);
  1453. goto ErrorExit;
  1454. }
  1455. hgad = rgFGM[0].pmsg->hgadMsg;
  1456. VALIDATE_EVENTGADGET_NOCONTEXT(gad);
  1457. pctxGad = pgad->GetContext();
  1458. for (idx = 0; idx < cMsgs; idx++) {
  1459. FGM_INFO & fgm = rgFGM[idx];
  1460. EventMsg * pmsg = fgm.pmsg;
  1461. VALIDATE_READ_PTR_(pmsg, pmsg->cbSize);
  1462. VALIDATE_FLAGS(fgm.nFlags, SGM_VALID);
  1463. if (pmsg->nMsg <= 0) {
  1464. PromptInvalid("Can not post private messages");
  1465. SetError(E_INVALIDARG);
  1466. goto ErrorExit;
  1467. }
  1468. if (TestFlag(fgm.nFlags, SGM_RECEIVECONTEXT)) {
  1469. PromptInvalid("Can not use SGM_RECEIVECONTEXT with FireGadgetMessage");
  1470. SetError(E_INVALIDARG);
  1471. goto ErrorExit;
  1472. }
  1473. hgad = pmsg->hgadMsg;
  1474. VALIDATE_EVENTGADGET_NOCONTEXT(gad);
  1475. pctxCheck = pgad->GetContext();
  1476. if (pctxCheck != pctxGad) {
  1477. PromptInvalid("All Gadgets must be inside the same Context");
  1478. SetError(DU_E_INVALIDCONTEXT);
  1479. goto ErrorExit;
  1480. }
  1481. //
  1482. // Store the validated Gadget back so that it doesn't need to be
  1483. // revalidated.
  1484. //
  1485. fgm.pvReserved = pgad;
  1486. }
  1487. hr = GetCoreSC()->xwFireMessagesNL(GetCoreSC(pctxGad), rgFGM, cMsgs, idQueue);
  1488. SET_RETURN(hr, TRUE);
  1489. END_RECV_NOCONTEXT();
  1490. }
  1491. /***************************************************************************\
  1492. *
  1493. * GetMessageEx (API)
  1494. *
  1495. \***************************************************************************/
  1496. DUSER_API BOOL WINAPI
  1497. GetMessageExA(
  1498. IN LPMSG lpMsg,
  1499. IN HWND hWnd,
  1500. IN UINT wMsgFilterMin,
  1501. IN UINT wMsgFilterMax)
  1502. {
  1503. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1504. Context * pctxThread = RawGetContext();
  1505. if (pctxThread == NULL) {
  1506. retval = GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
  1507. } else {
  1508. retval = GetCoreSC(pctxThread)->xwProcessNL(lpMsg, hWnd,
  1509. wMsgFilterMin, wMsgFilterMax, PM_REMOVE, CoreSC::smGetMsg | CoreSC::smAnsi);
  1510. }
  1511. END_RECV_NOCONTEXT();
  1512. }
  1513. DUSER_API BOOL WINAPI
  1514. GetMessageExW(
  1515. IN LPMSG lpMsg,
  1516. IN HWND hWnd,
  1517. IN UINT wMsgFilterMin,
  1518. IN UINT wMsgFilterMax)
  1519. {
  1520. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1521. Context * pctxThread = RawGetContext();
  1522. if (pctxThread == NULL) {
  1523. retval = GetMessageW(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
  1524. } else {
  1525. retval = GetCoreSC(pctxThread)->xwProcessNL(lpMsg, hWnd,
  1526. wMsgFilterMin, wMsgFilterMax, PM_REMOVE, CoreSC::smGetMsg);
  1527. }
  1528. END_RECV_NOCONTEXT();
  1529. }
  1530. /***************************************************************************\
  1531. *
  1532. * PeekMessageEx (API)
  1533. *
  1534. \***************************************************************************/
  1535. DUSER_API BOOL WINAPI
  1536. PeekMessageExA(
  1537. IN LPMSG lpMsg,
  1538. IN HWND hWnd,
  1539. IN UINT wMsgFilterMin,
  1540. IN UINT wMsgFilterMax,
  1541. IN UINT wRemoveMsg)
  1542. {
  1543. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1544. Context * pctxThread = RawGetContext();
  1545. if (pctxThread == NULL) {
  1546. retval = PeekMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
  1547. } else {
  1548. retval = GetCoreSC(pctxThread)->xwProcessNL(lpMsg, hWnd,
  1549. wMsgFilterMin, wMsgFilterMax, wRemoveMsg, CoreSC::smAnsi);
  1550. }
  1551. END_RECV_NOCONTEXT();
  1552. }
  1553. DUSER_API BOOL WINAPI
  1554. PeekMessageExW(
  1555. IN LPMSG lpMsg,
  1556. IN HWND hWnd,
  1557. IN UINT wMsgFilterMin,
  1558. IN UINT wMsgFilterMax,
  1559. IN UINT wRemoveMsg)
  1560. {
  1561. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1562. Context * pctxThread = RawGetContext();
  1563. if (pctxThread == NULL) {
  1564. retval = PeekMessageW(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
  1565. } else {
  1566. retval = GetCoreSC(pctxThread)->xwProcessNL(lpMsg, hWnd,
  1567. wMsgFilterMin, wMsgFilterMax, wRemoveMsg, 0);
  1568. }
  1569. END_RECV_NOCONTEXT();
  1570. }
  1571. /***************************************************************************\
  1572. *
  1573. * WaitMessageEx (API)
  1574. *
  1575. \***************************************************************************/
  1576. DUSER_API BOOL WINAPI
  1577. WaitMessageEx()
  1578. {
  1579. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1580. Context * pctxThread = RawGetContext();
  1581. if (pctxThread == NULL) {
  1582. retval = WaitMessage();
  1583. } else {
  1584. AssertInstance(pctxThread);
  1585. GetCoreSC(pctxThread)->WaitMessage();
  1586. retval = TRUE;
  1587. }
  1588. END_RECV_NOCONTEXT();
  1589. }
  1590. /***************************************************************************\
  1591. *
  1592. * RegisterGadgetMessage (API)
  1593. *
  1594. * RegisterGadgetMessage() defines a new private Gadget message that is
  1595. * guaranteed to be unique throughout the process. This MSGID can be used
  1596. * when calling SendGadgetEvent or PostGadgetEvent. The MSGID is only
  1597. * valid for the lifetime of the process.
  1598. *
  1599. * <remarks>
  1600. * Multiple calls to RegisterGadgetMessage() with the same ID will produce
  1601. * the same MSGID.
  1602. *
  1603. * RegisterGadgetMessage() differs in use from RegisterWindowMessage() in
  1604. * that Gadgets are encouraged to use RegisterGadgetMessage() for all
  1605. * private messages. This helps with version compatibility problems where
  1606. * newer Gadget control implementations may use additional message and could
  1607. * potentially overrun any static MSGID assignments.
  1608. *
  1609. * The MSGID's returned from RegisterGadgetMessage() and
  1610. * RegisterGadgetMessageString() are guaranteed to not conflict with each
  1611. * other. However, RegisterGadgetMessage() is the preferred mechanism for
  1612. * registering private messages because of the reduced likelihood of
  1613. * ID conflicts.
  1614. * </remarks>
  1615. *
  1616. * <return type="MSGID"> ID of new message or 0 if failed.</>
  1617. * <see type="function"> SendGadgetEvent</>
  1618. * <see type="function"> RegisterGadgetMessageString</>
  1619. * <see type="function"> UnregisterGadgetMessage</>
  1620. * <see type="function"> UnregisterGadgetMessageString</>
  1621. * <see type="function"> AddGadgetMessageHandler</>
  1622. * <see type="function"> RemoveGadgetMessageHandler</>
  1623. * <see type="struct"> GMSG</>
  1624. * <see type="article"> GadgetMessaging</>
  1625. *
  1626. \***************************************************************************/
  1627. DUSER_API MSGID WINAPI
  1628. RegisterGadgetMessage(
  1629. IN const GUID * pguid) // Unique GUID of message to register
  1630. {
  1631. HRESULT hr;
  1632. MSGID msgid;
  1633. BEGIN_RECV_NOCONTEXT(MSGID, PRID_Unused);
  1634. hr = DuEventPool::RegisterMessage(pguid, ptGlobal, &msgid);
  1635. SET_RETURN(hr, msgid);
  1636. END_RECV_NOCONTEXT();
  1637. }
  1638. /***************************************************************************\
  1639. *
  1640. * RegisterGadgetMessageString (API)
  1641. *
  1642. * RegisterGadgetMessageString() defines a new private Gadget message that is
  1643. * guaranteed to be unique throughout the process. This MSGID can be used
  1644. * when calling SendGadgetEvent() or PostGadgetEvent(). The MSGID is only
  1645. * valid for the lifetime of the process.
  1646. *
  1647. * <remarks>
  1648. * See RegisterGadgetMessage() for more information about MSGID's.
  1649. * </remarks>
  1650. *
  1651. * <return type="MSGID"> ID of new message or 0 if failed.</>
  1652. * <see type="function"> SendGadgetEvent</>
  1653. * <see type="function"> RegisterGadgetMessage</>
  1654. * <see type="function"> UnregisterGadgetMessage</>
  1655. * <see type="function"> UnregisterGadgetMessageString</>
  1656. * <see type="function"> AddGadgetMessageHandler</>
  1657. * <see type="function"> RemoveGadgetMessageHandler</>
  1658. * <see type="struct"> GMSG</>
  1659. * <see type="article"> GadgetMessaging</>
  1660. *
  1661. \***************************************************************************/
  1662. DUSER_API MSGID WINAPI
  1663. RegisterGadgetMessageString(
  1664. IN LPCWSTR pszName) // Unique string ID of message to register
  1665. {
  1666. HRESULT hr;
  1667. MSGID msgid;
  1668. BEGIN_RECV_NOCONTEXT(MSGID, PRID_Unused);
  1669. VALIDATE_STRINGW_PTR(pszName, 128);
  1670. hr = DuEventPool::RegisterMessage(pszName, ptGlobal, &msgid);
  1671. SET_RETURN(hr, msgid);
  1672. END_RECV_NOCONTEXT();
  1673. }
  1674. /***************************************************************************\
  1675. *
  1676. * UnregisterGadgetMessage (API)
  1677. *
  1678. * UnregisterGadgetMessage() decreases the reference count of a private
  1679. * message by one. When the reference count reaches 0, resources allocated
  1680. * to store information about that private message are released, and the
  1681. * MSGID is no longer valid.
  1682. *
  1683. * <return type="BOOL"> Message was successfully unregistered.</>
  1684. * <see type="function"> SendGadgetEvent</>
  1685. * <see type="function"> RegisterGadgetMessage</>
  1686. * <see type="function"> RegisterGadgetMessageString</>
  1687. * <see type="function"> UnregisterGadgetMessageString</>
  1688. * <see type="function"> AddGadgetMessageHandler</>
  1689. * <see type="function"> RemoveGadgetMessageHandler</>
  1690. * <see type="struct"> GMSG</>
  1691. * <see type="article"> GadgetMessaging</>
  1692. *
  1693. \***************************************************************************/
  1694. DUSER_API BOOL WINAPI
  1695. UnregisterGadgetMessage(
  1696. IN const GUID * pguid) // Unique GUID of message to unregister
  1697. {
  1698. HRESULT hr;
  1699. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1700. hr = DuEventPool::UnregisterMessage(pguid, ptGlobal);
  1701. SET_RETURN(hr, TRUE);
  1702. END_RECV_NOCONTEXT();
  1703. }
  1704. /***************************************************************************\
  1705. *
  1706. * UnregisterGadgetMessageString (API)
  1707. *
  1708. * UnregisterGadgetMessageString() decreases the reference count of a private
  1709. * message by one. When the reference count reaches 0, resources allocated
  1710. * to store information about that private message are released, and the
  1711. * MSGID is no longer valid.
  1712. *
  1713. * <return type="BOOL"> Message was successfully unregistered.</>
  1714. * <see type="function"> SendGadgetEvent</>
  1715. * <see type="function"> RegisterGadgetMessage</>
  1716. * <see type="function"> RegisterGadgetMessageString</>
  1717. * <see type="function"> UnregisterGadgetMessage</>
  1718. * <see type="function"> AddGadgetMessageHandler</>
  1719. * <see type="function"> RemoveGadgetMessageHandler</>
  1720. * <see type="struct"> GMSG</>
  1721. * <see type="article"> GadgetMessaging</>
  1722. *
  1723. \***************************************************************************/
  1724. DUSER_API BOOL WINAPI
  1725. UnregisterGadgetMessageString(
  1726. IN LPCWSTR pszName) // Unique string ID of message to register
  1727. {
  1728. HRESULT hr;
  1729. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1730. VALIDATE_STRINGW_PTR(pszName, 128);
  1731. hr = DuEventPool::UnregisterMessage(pszName, ptGlobal);
  1732. SET_RETURN(hr, TRUE);
  1733. END_RECV_NOCONTEXT();
  1734. }
  1735. //------------------------------------------------------------------------------
  1736. DUSER_API BOOL WINAPI
  1737. FindGadgetMessages(
  1738. IN const GUID ** rgpguid, // GUID's of messages to find
  1739. OUT MSGID * rgnMsg, // MSGID's of corresponding to messages
  1740. IN int cMsgs) // Number of messages
  1741. {
  1742. HRESULT hr;
  1743. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  1744. VALIDATE_RANGE(cMsgs, 1, 1000); // Ensure don't have an excessive number of lookups
  1745. hr = DuEventPool::FindMessages(rgpguid, rgnMsg, cMsgs, ptGlobal);
  1746. SET_RETURN(hr, TRUE);
  1747. END_RECV();
  1748. }
  1749. /***************************************************************************\
  1750. *
  1751. * AddGadgetMessageHandler (API)
  1752. *
  1753. * AddGadgetMessageHandler() adds a given Gadget to the list of message
  1754. * handlers for another Gadget. Messages that are sent directly to hgadMsg
  1755. * will also be sent to hgadHandler as an GMF_EVENT.
  1756. *
  1757. * <remarks>
  1758. * A message handler can be any Gadget. Once registered, hgadHandler will
  1759. * receive all messages sent to hgadMsg with a corresponding MSGID. Any
  1760. * valid public or private message can be listened it. If nMsg==0, all
  1761. * messages will be sent to hgadHandler.
  1762. *
  1763. * A single hgadHandler may be registered multiple times to handle different
  1764. * messages from hgadMsg.
  1765. * </remarks>
  1766. *
  1767. * <return type="BOOL"> Handler was successfully added.</>
  1768. * <see type="function"> SendGadgetEvent</>
  1769. * <see type="function"> RegisterGadgetMessage</>
  1770. * <see type="function"> RegisterGadgetMessageString</>
  1771. * <see type="function"> UnregisterGadgetMessage</>
  1772. * <see type="function"> UnregisterGadgetMessageString</>
  1773. * <see type="function"> RemoveGadgetMessageHandler</>
  1774. * <see type="struct"> GMSG</>
  1775. * <see type="article"> GadgetMessaging</>
  1776. *
  1777. \***************************************************************************/
  1778. DUSER_API BOOL WINAPI
  1779. AddGadgetMessageHandler(
  1780. IN HGADGET hgadMsg, // Gadget to attach to
  1781. IN MSGID nMsg, // Message to watch for
  1782. IN HGADGET hgadHandler) // Gadget to notify
  1783. {
  1784. DuEventGadget * pgadMsg;
  1785. DuEventGadget * pgadHandler;
  1786. HRESULT hr;
  1787. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1788. VALIDATE_EVENTGADGET(gadMsg);
  1789. VALIDATE_EVENTGADGET(gadHandler);
  1790. if (((nMsg < PRID_GlobalMin) && (nMsg > 0)) || (nMsg < 0)) {
  1791. PromptInvalid("nMsg must be a valid MSGID");
  1792. goto ErrorExit;
  1793. }
  1794. CHECK_MODIFY();
  1795. hr = pgadMsg->AddMessageHandler(nMsg, pgadHandler);
  1796. SET_RETURN(hr, TRUE);
  1797. END_RECV();
  1798. }
  1799. /***************************************************************************\
  1800. *
  1801. * RemoveGadgetMessageHandler (API)
  1802. *
  1803. * RemoveGadgetMessageHandler() removes the specified hgadHandler from the
  1804. * list of message handlers attached to hgadMsg. Only the first hgadHandler
  1805. * with a corresponding nMsg will be removed.
  1806. *
  1807. * <return type="BOOL"> Handler was successfully removed.</>
  1808. * <see type="function"> SendGadgetEvent</>
  1809. * <see type="function"> RegisterGadgetMessage</>
  1810. * <see type="function"> RegisterGadgetMessageString</>
  1811. * <see type="function"> UnregisterGadgetMessage</>
  1812. * <see type="function"> UnregisterGadgetMessageString</>
  1813. * <see type="function"> AddGadgetMessageHandler</>
  1814. * <see type="struct"> GMSG</>
  1815. * <see type="article"> GadgetMessaging</>
  1816. *
  1817. \***************************************************************************/
  1818. DUSER_API BOOL WINAPI
  1819. RemoveGadgetMessageHandler(
  1820. IN HGADGET hgadMsg, // Gadget to detach from
  1821. IN MSGID nMsg, // Message being watched for
  1822. IN HGADGET hgadHandler) // Gadget being notified
  1823. {
  1824. DuEventGadget * pgadMsg;
  1825. DuEventGadget * pgadHandler;
  1826. HRESULT hr;
  1827. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1828. VALIDATE_EVENTGADGET(gadMsg);
  1829. VALIDATE_EVENTGADGET(gadHandler);
  1830. if (((nMsg < PRID_GlobalMin) && (nMsg > 0)) || (nMsg < 0)) {
  1831. PromptInvalid("nMsg must be a valid MSGID");
  1832. goto ErrorExit;
  1833. }
  1834. CHECK_MODIFY();
  1835. hr = pgadMsg->RemoveMessageHandler(nMsg, pgadHandler);
  1836. SET_RETURN(hr, TRUE);
  1837. END_RECV();
  1838. }
  1839. /***************************************************************************\
  1840. *
  1841. * GetGadgetStyle (API)
  1842. *
  1843. * GetGadgetStyle() returns the current style of the given Gadget.
  1844. *
  1845. * <remarks>
  1846. * For a list of Gadget styles, see SetGadgetStyle().
  1847. * </remarks>
  1848. *
  1849. * <return type="UINT"> Current style of Gadget.</>
  1850. * <see type="function"> SetGadgetStyle</>
  1851. * <see type="article"> GadgetStyles</>
  1852. *
  1853. \***************************************************************************/
  1854. DUSER_API UINT WINAPI
  1855. GetGadgetStyle(
  1856. IN HGADGET hgad) // Handle of Gadget
  1857. {
  1858. DuVisual * pgad;
  1859. BEGIN_RECV(UINT, 0, ContextLock::edNone);
  1860. VALIDATE_VISUAL(gad);
  1861. retval = pgad->GetStyle();
  1862. END_RECV();
  1863. }
  1864. /***************************************************************************\
  1865. *
  1866. * SetGadgetStyle (API)
  1867. *
  1868. * SetGadgetStyle() changes the current style of the given Gadget. Only the
  1869. * styles specified by nMask are actually changed. If multiple style changes
  1870. * are requested, but any changes fail, the successfully change styles will
  1871. * not be reverted back.
  1872. *
  1873. * <param name="nNewStyle">
  1874. * nNewStyle can be a combination of the following flags:
  1875. * <table item="Value" desc="Meaning">
  1876. * GS_RELATIVE The position of the Gadget is internally stored
  1877. * relative to parent. This is the preferred style
  1878. * if the Gadget will be moved more frequently,
  1879. * such as when scrolling.
  1880. * GS_VISIBLE The Gadget is visible.
  1881. * GS_ENABLED The Gadget can receive input.
  1882. * GS_BUFFERED Drawing of the Gadget is double-buffered.
  1883. * GS_ALLOWSUBCLASS Gadget supports being subclassed.
  1884. * GS_WANTFOCUS Gadget can receive keyboard focus.
  1885. * GS_CLIPINSIDE Drawing of this Gadget will be clipped inside
  1886. * the Gadget.
  1887. * GS_CLIPSIBLINGS Drawing of this Gadget will exclude any area of
  1888. * overlapping siblings that are higher in z-order.
  1889. * GS_OPAQUE HINT: Support for composited drawing is
  1890. * unnecessary.
  1891. * GS_ZEROORIGIN Set the origin to (0,0)
  1892. * </table>
  1893. * </param>
  1894. *
  1895. * <return type="BOOL"> All style changes were successful.</>
  1896. * <see type="function"> GetGadgetStyle</>
  1897. * <see type="article"> GadgetStyles</>
  1898. *
  1899. \***************************************************************************/
  1900. DUSER_API BOOL WINAPI
  1901. SetGadgetStyle(
  1902. IN HGADGET hgadChange, // Gadget to change
  1903. IN UINT nNewStyle, // New style
  1904. IN UINT nMask) // Style bits to change
  1905. {
  1906. DuVisual * pgadChange;
  1907. HRESULT hr;
  1908. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1909. VALIDATE_VISUAL(gadChange);
  1910. VALIDATE_FLAGS(nNewStyle, GS_VALID);
  1911. VALIDATE_FLAGS(nMask, GS_VALID);
  1912. CHECK_MODIFY();
  1913. hr = pgadChange->xdSetStyle(nNewStyle, nMask);
  1914. SET_RETURN(hr, TRUE);
  1915. END_RECV();
  1916. }
  1917. //------------------------------------------------------------------------------
  1918. DUSER_API PRID WINAPI
  1919. RegisterGadgetProperty(
  1920. IN const GUID * pguid) // Unique GUID of message to register
  1921. {
  1922. HRESULT hr;
  1923. PRID prid;
  1924. BEGIN_RECV_NOCONTEXT(PRID, PRID_Unused);
  1925. hr = DuVisual::RegisterPropertyNL(pguid, ptGlobal, &prid);
  1926. SET_RETURN(hr, prid);
  1927. END_RECV_NOCONTEXT();
  1928. }
  1929. //------------------------------------------------------------------------------
  1930. DUSER_API BOOL WINAPI
  1931. UnregisterGadgetProperty(
  1932. const GUID * pguid)
  1933. {
  1934. HRESULT hr;
  1935. BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
  1936. hr = DuVisual::UnregisterPropertyNL(pguid, ptGlobal);
  1937. SET_RETURN(hr, TRUE);
  1938. END_RECV_NOCONTEXT();
  1939. }
  1940. //------------------------------------------------------------------------------
  1941. DUSER_API BOOL WINAPI
  1942. GetGadgetProperty(HGADGET hgad, PRID id, void ** ppvValue)
  1943. {
  1944. DuVisual * pgad;
  1945. HRESULT hr;
  1946. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  1947. VALIDATE_VISUAL(gad);
  1948. VALIDATE_WRITE_PTR_(ppvValue, sizeof(ppvValue));
  1949. CHECK_MODIFY();
  1950. hr = pgad->GetProperty(id, ppvValue);
  1951. SET_RETURN(hr, TRUE);
  1952. END_RECV();
  1953. }
  1954. //------------------------------------------------------------------------------
  1955. DUSER_API BOOL WINAPI
  1956. SetGadgetProperty(HGADGET hgad, PRID id, void * pvValue)
  1957. {
  1958. DuVisual * pgad;
  1959. HRESULT hr;
  1960. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1961. VALIDATE_VISUAL(gad);
  1962. CHECK_MODIFY();
  1963. hr = pgad->SetProperty(id, pvValue);
  1964. SET_RETURN(hr, TRUE);
  1965. END_RECV();
  1966. }
  1967. //---------------------------------------------------------------------------
  1968. DUSER_API BOOL WINAPI
  1969. RemoveGadgetProperty(HGADGET hgad, PRID id)
  1970. {
  1971. DuVisual * pgad;
  1972. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1973. VALIDATE_VISUAL(gad);
  1974. CHECK_MODIFY();
  1975. pgad->RemoveProperty(id, FALSE /* Can't free memory for Global property*/);
  1976. retval = TRUE;
  1977. END_RECV();
  1978. }
  1979. //---------------------------------------------------------------------------
  1980. DUSER_API BOOL WINAPI
  1981. EnumGadgets(HGADGET hgadEnum, GADGETENUMPROC pfnProc, void * pvData, UINT nFlags)
  1982. {
  1983. DuVisual * pgadEnum;
  1984. HRESULT hr;
  1985. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  1986. VALIDATE_FLAGS(nFlags, GENUM_VALID);
  1987. VALIDATE_VISUAL(gadEnum);
  1988. VALIDATE_CODE_PTR(pfnProc);
  1989. CHECK_MODIFY();
  1990. hr = pgadEnum->xwEnumGadgets(pfnProc, pvData, nFlags);
  1991. SET_RETURN(hr, TRUE);
  1992. END_RECV();
  1993. }
  1994. /***************************************************************************\
  1995. *
  1996. * GetGadgetSize (API)
  1997. *
  1998. * GetGadgetSize() is a high-performance mechanism of retreiving the Gadget's
  1999. * logical size.
  2000. *
  2001. * <return type="BOOL"> Successfully returned size in logical pixels.</>
  2002. * <see type="function"> GetGadgetRect</>
  2003. * <see type="function"> SetGadgetRect</>
  2004. * <see type="article"> GadgetStyles</>
  2005. *
  2006. \***************************************************************************/
  2007. DUSER_API BOOL WINAPI
  2008. GetGadgetSize(
  2009. IN HGADGET hgad, // Handle of Gadget
  2010. OUT SIZE * psizeLogicalPxl) // Size in logical pixels
  2011. {
  2012. DuVisual * pgad;
  2013. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  2014. VALIDATE_VISUAL(gad);
  2015. VALIDATE_WRITE_PTR_(psizeLogicalPxl, sizeof(SIZE));
  2016. pgad->GetSize(psizeLogicalPxl);
  2017. retval = TRUE;
  2018. END_RECV();
  2019. }
  2020. /***************************************************************************\
  2021. *
  2022. * GetGadgetRect (API)
  2023. *
  2024. * GetGadgetRect() is a flexible mechanism of retreiving the Gadget's
  2025. * logical rectangle or actual bounding box.
  2026. *
  2027. * <param name=nFlags>
  2028. * nFlags can be a combination of the following flags:
  2029. * <table item="Value" desc="Meaning">
  2030. * SGR_CLIENT Coordinates are relative to the Gadget itself.
  2031. * SGR_PARENT Coordinates are relative to the Gadget's parent.
  2032. * SGR_CONTAINER Coordinates are relative to the Gadget's root
  2033. * container.
  2034. * SGR_DESKTOP Coordinates are relative to the Windows desktop.
  2035. * SGR_ACTUAL Return the bounding rectangle of the Gadget. If
  2036. * this flag is specified, a bounding box is
  2037. * computed from all transformations applied from
  2038. * the root to the Gadget itself. If this flag is
  2039. * not specified, the rectangle returned will be in
  2040. * logical coordinates.
  2041. * </table>
  2042. * </param>
  2043. *
  2044. * <return type="BOOL"> Rectangle was successfully retreived.</>
  2045. * <see type="function"> SetGadgetRect</>
  2046. * <see type="function"> GetGadgetRotation</>
  2047. * <see type="function"> SetGadgetRotation</>
  2048. * <see type="function"> GetGadgetScale</>
  2049. * <see type="function"> SetGadgetScale</>
  2050. *
  2051. \***************************************************************************/
  2052. DUSER_API BOOL WINAPI
  2053. GetGadgetRect(
  2054. IN HGADGET hgad, // Handle of Gadget
  2055. OUT RECT * prcPxl, // Rectangle in specified pixels
  2056. IN UINT nFlags) // Rectangle to retrieve
  2057. {
  2058. DuVisual * pgad;
  2059. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  2060. VALIDATE_FLAGS(nFlags, SGR_VALID_GET);
  2061. VALIDATE_VISUAL(gad);
  2062. VALIDATE_WRITE_PTR_(prcPxl, sizeof(RECT));
  2063. if (TestFlag(nFlags, SGR_ACTUAL)) {
  2064. AssertMsg(0, "TODO: Not Implemented");
  2065. } else {
  2066. pgad->GetLogRect(prcPxl, nFlags);
  2067. retval = TRUE;
  2068. }
  2069. END_RECV();
  2070. }
  2071. /***************************************************************************\
  2072. *
  2073. * SetGadgetRect (API)
  2074. *
  2075. * SetGadgetRect() changes the size or position of a given Gadget.
  2076. *
  2077. * <param name=nFlags>
  2078. * nFlags can be a combination of the following flags:
  2079. * <table item="Value" desc="Meaning">
  2080. * SGR_MOVE Move to Gadget to a new location specified by
  2081. * x, y.
  2082. * SGR_SIZE Change the Gadget's size to width w and height h.
  2083. * SGR_CLIENT Coordinates are relative to the Gadget itself.
  2084. * SGR_PARENT Coordinates are relative to the Gadget's parent.
  2085. * SGR_CONTAINER Coordinates are relative to the Gadget's root
  2086. * container.
  2087. * SGR_DESKTOP Coordinates are relative to the Windows desktop.
  2088. * SGR_OFFSET Coordinates are relative to the Gadget's current
  2089. * location.
  2090. * SGR_ACTUAL Return the bounding rectangle of the Gadget. If
  2091. * this flag is specified, a bounding box is
  2092. * computed from all transformations applied from
  2093. * the root to the Gadget itself. If this flag is
  2094. * not specified, the rectangle returned will be in
  2095. * logical coordinates.
  2096. * </table>
  2097. * </param>
  2098. *
  2099. * <return type="BOOL"> Rectangle was successfully retreived.</>
  2100. * <see type="function"> SetGadgetRect</>
  2101. * <see type="function"> GetGadgetRotation</>
  2102. * <see type="function"> SetGadgetRotation</>
  2103. * <see type="function"> GetGadgetScale</>
  2104. * <see type="function"> SetGadgetScale</>
  2105. *
  2106. \***************************************************************************/
  2107. DUSER_API BOOL WINAPI
  2108. SetGadgetRect(
  2109. IN HGADGET hgadChange, // Gadget to change
  2110. IN int x, // New horizontal position
  2111. IN int y, // New vertical position
  2112. IN int w, // New width
  2113. IN int h, // New height
  2114. IN UINT nFlags) // Flags specifying what to change
  2115. {
  2116. DuVisual * pgadChange;
  2117. HRESULT hr;
  2118. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2119. VALIDATE_FLAGS(nFlags, SGR_VALID_SET);
  2120. VALIDATE_VISUAL(gadChange);
  2121. CHECK_MODIFY();
  2122. if (pgadChange->IsRoot()) {
  2123. if (TestFlag(nFlags, SGR_MOVE)) {
  2124. PromptInvalid("Can not move a RootGadget");
  2125. SetError(E_INVALIDARG);
  2126. goto ErrorExit;
  2127. }
  2128. }
  2129. //
  2130. // Ensure that size is non-negative
  2131. //
  2132. if (TestFlag(nFlags, SGR_SIZE)) {
  2133. if (w < 0) {
  2134. w = 0;
  2135. }
  2136. if (h < 0) {
  2137. h = 0;
  2138. }
  2139. }
  2140. if (TestFlag(nFlags, SGR_ACTUAL)) {
  2141. // AssertMsg(0, "TODO: Not Implemented");
  2142. ClearFlag(nFlags, SGR_ACTUAL);
  2143. hr = pgadChange->xdSetLogRect(x, y, w, h, nFlags);
  2144. } else {
  2145. hr = pgadChange->xdSetLogRect(x, y, w, h, nFlags);
  2146. }
  2147. SET_RETURN(hr, TRUE);
  2148. END_RECV();
  2149. }
  2150. /***************************************************************************\
  2151. *
  2152. * FindGadgetFromPoint (API)
  2153. *
  2154. * FindGadgetFromPoint() determines which Gadget a contains the specified
  2155. * point.
  2156. *
  2157. * <return type="HGADGET"> Gadget containing point or NULL for none.</>
  2158. *
  2159. \***************************************************************************/
  2160. DUSER_API HGADGET WINAPI
  2161. FindGadgetFromPoint(
  2162. IN HGADGET hgad, // Gadget to search from
  2163. IN POINT ptContainerPxl, // Point to search from in container pixels
  2164. IN UINT nStyle, // Required style flags
  2165. OUT POINT * pptClientPxl) // Optional translated point in client pixels.
  2166. {
  2167. DuVisual * pgad;
  2168. BEGIN_RECV(HGADGET, NULL, ContextLock::edNone);
  2169. VALIDATE_FLAGS(nStyle, GS_VALID);
  2170. VALIDATE_VISUAL(gad);
  2171. VALIDATE_WRITE_PTR_OR_NULL_(pptClientPxl, sizeof(POINT));
  2172. retval = (HGADGET) GetHandle(pgad->FindFromPoint(ptContainerPxl, nStyle, pptClientPxl));
  2173. END_RECV();
  2174. }
  2175. /***************************************************************************\
  2176. *
  2177. * MapGadgetPoints (API)
  2178. *
  2179. * MapGadgetPoints() converts a set of points in client-pixels relative to
  2180. * one Gadget into points in client-pixels relative to another Gadget.
  2181. *
  2182. * <return type="HGADGET"> Gadget containing point or NULL for none.</>
  2183. *
  2184. \***************************************************************************/
  2185. DUSER_API BOOL WINAPI
  2186. MapGadgetPoints(
  2187. IN HGADGET hgadFrom,
  2188. IN HGADGET hgadTo,
  2189. IN OUT POINT * rgptClientPxl,
  2190. IN int cPts)
  2191. {
  2192. DuVisual * pgadFrom, * pgadTo;
  2193. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  2194. VALIDATE_VISUAL(gadFrom);
  2195. VALIDATE_VISUAL(gadTo);
  2196. VALIDATE_WRITE_PTR_(rgptClientPxl, sizeof(POINT) * cPts);
  2197. if (pgadFrom->GetRoot() != pgadTo->GetRoot()) {
  2198. PromptInvalid("Must be in the same tree");
  2199. SetError(E_INVALIDARG);
  2200. goto ErrorExit;
  2201. }
  2202. DuVisual::MapPoints(pgadFrom, pgadTo, rgptClientPxl, cPts);
  2203. retval = TRUE;
  2204. END_RECV();
  2205. }
  2206. /***************************************************************************\
  2207. *
  2208. * SetGadgetOrder (API)
  2209. *
  2210. * SetGadgetOrder() changes the Gadget's z-order relative to its siblings.
  2211. * The parent of the Gadget is not changed.
  2212. *
  2213. * <param name=nFlags>
  2214. * nFlags can be a combination of the following flags:
  2215. * <table item="Value" desc="Meaning">
  2216. * GORDER_ANY The order does not matter.
  2217. * GORDER_BEFORE Move this gadget in-front of sibling hgadOther.
  2218. * GORDER_BEHIND Move this gadget behind sibling hgadOther.
  2219. * GORDER_TOP Move this gadget to front of sibling z-order.
  2220. * GORDER_BOTTOM Move this gadget to bottom of sibling z-order.
  2221. * GORDER_FORWARD Move this gadget forward in sibling z-order.
  2222. * GORDER_BACKWARD Move this gadget backward in sibling z-order.
  2223. * </table>
  2224. * </param>
  2225. *
  2226. * <return type="BOOL"> Gadget z-order was successfully changed.</>
  2227. * <see type="function"> SetGadgetParent</>
  2228. *
  2229. \***************************************************************************/
  2230. DUSER_API BOOL WINAPI
  2231. SetGadgetOrder(
  2232. IN HGADGET hgadMove, // Gadget to be moved
  2233. IN HGADGET hgadOther, // Gadget to moved relative to
  2234. IN UINT nCmd) // Type of move
  2235. {
  2236. DuVisual * pgadMove;
  2237. DuVisual * pgadOther;
  2238. HRESULT hr;
  2239. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2240. VALIDATE_RANGE(nCmd, GORDER_MIN, GORDER_MAX);
  2241. VALIDATE_VISUAL(gadMove);
  2242. VALIDATE_VISUAL_OR_NULL(gadOther);
  2243. CHECK_MODIFY();
  2244. hr = pgadMove->xdSetOrder(pgadOther, nCmd);
  2245. SET_RETURN(hr, TRUE);
  2246. END_RECV();
  2247. }
  2248. /***************************************************************************\
  2249. *
  2250. * SetGadgetParent (API)
  2251. *
  2252. * SetGadgetParent() changes the Gadget's parent.
  2253. *
  2254. * <param name=nFlags>
  2255. * nFlags can be a combination of the following flags:
  2256. * <table item="Value" desc="Meaning">
  2257. * GORDER_ANY The order does not matter.
  2258. * GORDER_BEFORE Move this gadget in-front of sibling hgadOther.
  2259. * GORDER_BEHIND Move this gadget behind sibling hgadOther.
  2260. * GORDER_TOP Move this gadget to front of sibling z-order.
  2261. * GORDER_BOTTOM Move this gadget to bottom of sibling z-order.
  2262. * GORDER_FORWARD Move this gadget forward in sibling z-order.
  2263. * GORDER_BACKWARD Move this gadget backward in sibling z-order.
  2264. * </table>
  2265. * </param>
  2266. *
  2267. * <return type="BOOL"> Gadget parent and z-order were successfully changed.</>
  2268. * <see type="function"> SetGadgetOrder</>
  2269. * <see type="function"> GetGadget</>
  2270. *
  2271. \***************************************************************************/
  2272. DUSER_API BOOL WINAPI
  2273. SetGadgetParent(
  2274. IN HGADGET hgadMove, // Gadget to be moved
  2275. IN HGADGET hgadParent, // New parent
  2276. IN HGADGET hgadOther, // Gadget to moved relative to
  2277. IN UINT nCmd) // Type of move
  2278. {
  2279. DuVisual * pgadMove;
  2280. DuVisual * pgadParent;
  2281. DuVisual * pgadOther;
  2282. HRESULT hr;
  2283. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2284. VALIDATE_RANGE(nCmd, GORDER_MIN, GORDER_MAX);
  2285. VALIDATE_VISUAL(gadMove);
  2286. VALIDATE_VISUAL_OR_NULL(gadParent);
  2287. VALIDATE_VISUAL_OR_NULL(gadOther);
  2288. CHECK_MODIFY();
  2289. if (pgadMove->IsRoot()) {
  2290. PromptInvalid("Can not change a RootGadget's parent");
  2291. SetError(E_INVALIDARG);
  2292. goto ErrorExit;
  2293. }
  2294. //
  2295. // Check that can become a child of the specified parent
  2296. //
  2297. if ((!pgadMove->IsRelative()) && pgadParent->IsRelative()) {
  2298. PromptInvalid("Can not set non-relative child to a relative parent");
  2299. SetError(DU_E_BADCOORDINATEMAP);
  2300. goto ErrorExit;
  2301. }
  2302. //
  2303. // DuVisual::xdSetParent() handles if pgadParent is NULL and will move to the
  2304. // parking window.
  2305. //
  2306. hr = pgadMove->xdSetParent(pgadParent, pgadOther, nCmd);
  2307. SET_RETURN(hr, TRUE);
  2308. END_RECV();
  2309. }
  2310. /***************************************************************************\
  2311. *
  2312. * GetGadget (API)
  2313. *
  2314. * GetGadget() retrieves the Gadget that has the specified relationship to
  2315. * the specified Gadget.
  2316. *
  2317. * <param name=nFlags>
  2318. * nFlags can be a combination of the following flags:
  2319. * <table item="Value" desc="Meaning">
  2320. * GG_PARENT Return the parent of the specified Gadget.
  2321. * GG_NEXT Return the next sibling behind the specified
  2322. * Gadget.
  2323. * GG_PREV Return the previous sibling before the
  2324. * specified Gadget.
  2325. * GG_TOPCHILD Return the Gadget's top z-ordered child.
  2326. * GG_BOTTOMCHILD Return the Gadget's bottom z-ordered child.
  2327. * </table>
  2328. * </param>
  2329. *
  2330. * <return type="BOOL"> Related Gadget or NULL for none.</>
  2331. * <see type="function"> SetGadgetOrder</>
  2332. * <see type="function"> SetGadgetParent</>
  2333. *
  2334. \***************************************************************************/
  2335. DUSER_API HGADGET WINAPI
  2336. GetGadget(
  2337. IN HGADGET hgad, // Handle of Gadget
  2338. IN UINT nCmd) // Relationship
  2339. {
  2340. DuVisual * pgad;
  2341. BEGIN_RECV(HGADGET, NULL, ContextLock::edNone);
  2342. VALIDATE_VISUAL(gad);
  2343. VALIDATE_RANGE(nCmd, GG_MIN, GG_MAX);
  2344. retval = (HGADGET) GetHandle(pgad->GetGadget(nCmd));
  2345. END_RECV();
  2346. }
  2347. /***************************************************************************\
  2348. *
  2349. * InvalidateGadget (API)
  2350. *
  2351. * InvalidateGadget() marks a Gadget to be repainted during the next painting
  2352. * cycle.
  2353. *
  2354. * <return type="BOOL"> Gadget was successfully invalidated.</>
  2355. * <see type="message"> GM_PAINT</>
  2356. *
  2357. \***************************************************************************/
  2358. DUSER_API BOOL WINAPI
  2359. InvalidateGadget(
  2360. IN HGADGET hgad) // Gadget to repaint
  2361. {
  2362. DuVisual * pgad;
  2363. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2364. VALIDATE_VISUAL(gad);
  2365. CHECK_MODIFY();
  2366. pgad->Invalidate();
  2367. retval = TRUE;
  2368. END_RECV();
  2369. }
  2370. //---------------------------------------------------------------------------
  2371. DUSER_API UINT WINAPI
  2372. GetGadgetMessageFilter(HGADGET hgad, void * pvCookie)
  2373. {
  2374. DuEventGadget * pgad;
  2375. BEGIN_RECV(UINT, 0, ContextLock::edNone);
  2376. VALIDATE_EVENTGADGET(gad);
  2377. VALIDATE_VALUE(pvCookie, NULL);
  2378. retval = (pgad->GetFilter() & GMFI_VALID);
  2379. END_RECV();
  2380. }
  2381. //---------------------------------------------------------------------------
  2382. DUSER_API BOOL WINAPI
  2383. SetGadgetMessageFilter(HGADGET hgadChange, void * pvCookie, UINT nNewFilter, UINT nMask)
  2384. {
  2385. DuEventGadget * pgadChange;
  2386. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2387. VALIDATE_EVENTGADGET(gadChange);
  2388. VALIDATE_FLAGS(nNewFilter, GMFI_VALID);
  2389. VALIDATE_VALUE(pvCookie, NULL);
  2390. CHECK_MODIFY();
  2391. pgadChange->SetFilter(nNewFilter, nMask);
  2392. retval = TRUE;
  2393. END_RECV();
  2394. }
  2395. //---------------------------------------------------------------------------
  2396. DUSER_API BOOL WINAPI
  2397. ForwardGadgetMessage(HGADGET hgadRoot, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT * pr)
  2398. {
  2399. DuVisual * pgadRoot;
  2400. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2401. VALIDATE_VISUAL(gadRoot);
  2402. VALIDATE_WRITE_PTR(pr);
  2403. CHECK_MODIFY();
  2404. retval = GdForwardMessage(pgadRoot, nMsg, wParam, lParam, pr);
  2405. END_RECV();
  2406. }
  2407. //---------------------------------------------------------------------------
  2408. DUSER_API BOOL WINAPI
  2409. DrawGadgetTree(HGADGET hgadDraw, HDC hdcDraw, const RECT * prcDraw, UINT nFlags)
  2410. {
  2411. DuVisual * pgadDraw;
  2412. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2413. VALIDATE_VISUAL(gadDraw);
  2414. VALIDATE_READ_PTR_OR_NULL_(prcDraw, sizeof(RECT));
  2415. VALIDATE_FLAGS(nFlags, GDRAW_VALID);
  2416. retval = GdxrDrawGadgetTree(pgadDraw, hdcDraw, prcDraw, nFlags);
  2417. END_RECV();
  2418. }
  2419. /***************************************************************************\
  2420. *****************************************************************************
  2421. *
  2422. * DirectUser GADGET API
  2423. *
  2424. * <package name="Msg"/>
  2425. *
  2426. *****************************************************************************
  2427. \***************************************************************************/
  2428. /***************************************************************************\
  2429. *
  2430. * DUserRegisterGuts
  2431. *
  2432. * DUserRegisterGuts() registers the implementation of a MsgClass.
  2433. *
  2434. \***************************************************************************/
  2435. DUSER_API HCLASS WINAPI
  2436. DUserRegisterGuts(
  2437. IN OUT DUser::MessageClassGuts * pmcInfo) // Class information
  2438. {
  2439. MsgClass * pmcNew;
  2440. HRESULT hr;
  2441. BEGIN_RECV_NOCONTEXT(HCLASS, NULL);
  2442. VALIDATE_WRITE_STRUCT(pmcInfo, DUser::MessageClassGuts);
  2443. hr = GetClassLibrary()->RegisterGutsNL(pmcInfo, &pmcNew);
  2444. SET_RETURN(hr, (HCLASS) GetHandle(pmcNew));
  2445. END_RECV_NOCONTEXT();
  2446. }
  2447. /***************************************************************************\
  2448. *
  2449. * DUserRegisterStub
  2450. *
  2451. * DUserRegisterStub() registers a Stub for a MsgClass
  2452. *
  2453. \***************************************************************************/
  2454. DUSER_API HCLASS WINAPI
  2455. DUserRegisterStub(
  2456. IN OUT DUser::MessageClassStub * pmcInfo) // Class information
  2457. {
  2458. MsgClass * pmcFind;
  2459. HRESULT hr;
  2460. BEGIN_RECV_NOCONTEXT(HCLASS, NULL);
  2461. VALIDATE_WRITE_STRUCT(pmcInfo, DUser::MessageClassStub);
  2462. hr = GetClassLibrary()->RegisterStubNL(pmcInfo, &pmcFind);
  2463. SET_RETURN(hr, (HCLASS) GetHandle(pmcFind));
  2464. END_RECV_NOCONTEXT();
  2465. }
  2466. /***************************************************************************\
  2467. *
  2468. * DUserRegisterSuper
  2469. *
  2470. * DUserRegisterSuper() registers a Super for a MsgClass
  2471. *
  2472. \***************************************************************************/
  2473. DUSER_API HCLASS WINAPI
  2474. DUserRegisterSuper(
  2475. IN OUT DUser::MessageClassSuper * pmcInfo) // Class information
  2476. {
  2477. MsgClass * pmcFind;
  2478. HRESULT hr;
  2479. BEGIN_RECV_NOCONTEXT(HCLASS, NULL);
  2480. VALIDATE_WRITE_STRUCT(pmcInfo, DUser::MessageClassSuper);
  2481. hr = GetClassLibrary()->RegisterSuperNL(pmcInfo, &pmcFind);
  2482. SET_RETURN(hr, (HCLASS) GetHandle(pmcFind));
  2483. END_RECV_NOCONTEXT();
  2484. }
  2485. /***************************************************************************\
  2486. *
  2487. * DUserFindClass
  2488. *
  2489. * DUserFindClass() finds a previously registered Gadget Class
  2490. *
  2491. \***************************************************************************/
  2492. DUSER_API HCLASS WINAPI
  2493. DUserFindClass(
  2494. IN LPCWSTR pszName,
  2495. IN DWORD nVersion)
  2496. {
  2497. const MsgClass * pmcFind = NULL;
  2498. ATOM atom;
  2499. HRESULT hr;
  2500. BEGIN_RECV_NOCONTEXT(HCLASS, NULL);
  2501. VALIDATE_VALUE(nVersion, 1); // Currently, all classes are version 1
  2502. atom = FindAtomW(pszName);
  2503. if (atom == 0) {
  2504. hr = DU_E_NOTFOUND;
  2505. } else {
  2506. pmcFind = GetClassLibrary()->FindClass(atom);
  2507. hr = S_OK;
  2508. }
  2509. SET_RETURN(hr, (HCLASS) GetHandle(pmcFind));
  2510. END_RECV_NOCONTEXT();
  2511. }
  2512. /***************************************************************************\
  2513. *
  2514. * DUserBuildGadget
  2515. *
  2516. * DUserBuildGadget() creates a fully initialized Gadget using the specified
  2517. * MsgClass.
  2518. *
  2519. \***************************************************************************/
  2520. DUSER_API DUser::Gadget * WINAPI
  2521. DUserBuildGadget(
  2522. IN HCLASS hcl, // Class to construct
  2523. IN DUser::Gadget::ConstructInfo * pciData) // Construction data
  2524. {
  2525. MsgClass * pmc = ValidateMsgClass(hcl);
  2526. if (pmc == NULL) {
  2527. return NULL;
  2528. }
  2529. MsgObject * pmoNew;
  2530. HRESULT hr = pmc->xwBuildObject(&pmoNew, pciData);
  2531. if (FAILED(hr)) {
  2532. return NULL;
  2533. }
  2534. return pmoNew->GetGadget();
  2535. }
  2536. //------------------------------------------------------------------------------
  2537. DUSER_API BOOL WINAPI
  2538. DUserInstanceOf(DUser::Gadget * pg, HCLASS hclTest)
  2539. {
  2540. MsgObject * pmo;
  2541. MsgClass * pmcTest;
  2542. pmo = MsgObject::CastMsgObject(pg);
  2543. if (pmo == NULL) {
  2544. PromptInvalid("The specified Gadget is invalid");
  2545. goto Error;
  2546. }
  2547. pmcTest = ValidateMsgClass(hclTest);
  2548. if (pmcTest == NULL) {
  2549. PromptInvalid("The specified class is invalid");
  2550. goto Error;
  2551. }
  2552. return pmo->InstanceOf(pmcTest);
  2553. Error:
  2554. SetError(E_INVALIDARG);
  2555. return FALSE;
  2556. }
  2557. //------------------------------------------------------------------------------
  2558. DUSER_API DUser::Gadget * WINAPI
  2559. DUserCastClass(DUser::Gadget * pg, HCLASS hclTest)
  2560. {
  2561. MsgObject * pmo;
  2562. MsgClass * pmcTest;
  2563. //
  2564. // A NULL MsgObject is a valid input, so return NULL.
  2565. //
  2566. pmo = MsgObject::CastMsgObject(pg);
  2567. if (pmo == NULL) {
  2568. return NULL;
  2569. }
  2570. //
  2571. // The HCLASS must be valid.
  2572. //
  2573. pmcTest = ValidateMsgClass(hclTest);
  2574. if (pmcTest == NULL) {
  2575. PromptInvalid("The specified class is invalid");
  2576. goto Error;
  2577. }
  2578. return pmo->CastClass(pmcTest);
  2579. Error:
  2580. SetError(E_INVALIDARG);
  2581. return NULL;
  2582. }
  2583. //------------------------------------------------------------------------------
  2584. DUSER_API DUser::Gadget * WINAPI
  2585. DUserCastDirect(HGADGET hgad)
  2586. {
  2587. return MsgObject::CastGadget(hgad);
  2588. }
  2589. //------------------------------------------------------------------------------
  2590. DUSER_API HGADGET WINAPI
  2591. DUserCastHandle(DUser::Gadget * pg)
  2592. {
  2593. return MsgObject::CastHandle(pg);
  2594. }
  2595. //------------------------------------------------------------------------------
  2596. DUSER_API void * WINAPI
  2597. DUserGetGutsData(DUser::Gadget * pg, HCLASS hclData)
  2598. {
  2599. MsgObject * pmo;
  2600. MsgClass * pmcData;
  2601. pmo = MsgObject::CastMsgObject(pg);
  2602. if (pmo == NULL) {
  2603. PromptInvalid("The specified Gadget is invalid");
  2604. goto Error;
  2605. }
  2606. pmcData = ValidateMsgClass(hclData);
  2607. if (pmcData == NULL) {
  2608. PromptInvalid("The specified class is invalid");
  2609. goto Error;
  2610. }
  2611. return pmo->GetGutsData(pmcData);
  2612. Error:
  2613. SetError(E_INVALIDARG);
  2614. return NULL;
  2615. }
  2616. /***************************************************************************\
  2617. *****************************************************************************
  2618. *
  2619. * DirectUser GADGET API
  2620. *
  2621. * <package name="Lava"/>
  2622. *
  2623. *****************************************************************************
  2624. \***************************************************************************/
  2625. //---------------------------------------------------------------------------
  2626. DUSER_API BOOL WINAPI
  2627. AttachWndProcA(HWND hwnd, ATTACHWNDPROC pfn, void * pvThis)
  2628. {
  2629. HRESULT hr = GdAttachWndProc(hwnd, pfn, pvThis, TRUE);
  2630. if (SUCCEEDED(hr)) {
  2631. return TRUE;
  2632. } else {
  2633. SetError(hr);
  2634. return FALSE;
  2635. }
  2636. }
  2637. //---------------------------------------------------------------------------
  2638. DUSER_API BOOL WINAPI
  2639. AttachWndProcW(HWND hwnd, ATTACHWNDPROC pfn, void * pvThis)
  2640. {
  2641. HRESULT hr = GdAttachWndProc(hwnd, pfn, pvThis, FALSE);
  2642. if (SUCCEEDED(hr)) {
  2643. return TRUE;
  2644. } else {
  2645. SetError(hr);
  2646. return FALSE;
  2647. }
  2648. }
  2649. //---------------------------------------------------------------------------
  2650. DUSER_API BOOL WINAPI
  2651. DetachWndProc(HWND hwnd, ATTACHWNDPROC pfn, void * pvThis)
  2652. {
  2653. HRESULT hr = GdDetachWndProc(hwnd, pfn, pvThis);
  2654. if (SUCCEEDED(hr)) {
  2655. return TRUE;
  2656. } else {
  2657. SetError(hr);
  2658. return FALSE;
  2659. }
  2660. }
  2661. /***************************************************************************\
  2662. *****************************************************************************
  2663. *
  2664. * DirectUser MOTION API
  2665. *
  2666. * <package name="Motion"/>
  2667. *
  2668. *****************************************************************************
  2669. \***************************************************************************/
  2670. //---------------------------------------------------------------------------
  2671. DUSER_API HTRANSITION WINAPI
  2672. CreateTransition(const GTX_TRXDESC * ptx)
  2673. {
  2674. BEGIN_RECV(HTRANSITION, NULL, ContextLock::edDefer);
  2675. VALIDATE_READ_PTR_(ptx, sizeof(GTX_TRXDESC));
  2676. CHECK_MODIFY();
  2677. retval = (HTRANSITION) GetHandle(GdCreateTransition(ptx));
  2678. END_RECV();
  2679. }
  2680. //---------------------------------------------------------------------------
  2681. DUSER_API BOOL WINAPI
  2682. PlayTransition(HTRANSITION htrx, const GTX_PLAY * pgx)
  2683. {
  2684. Transition * ptrx;
  2685. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2686. VALIDATE_TRANSITION(trx);
  2687. VALIDATE_READ_PTR_(pgx, sizeof(GTX_PLAY));
  2688. VALIDATE_FLAGS(pgx->nFlags, GTX_EXEC_VALID);
  2689. retval = ptrx->Play(pgx);
  2690. END_RECV();
  2691. }
  2692. //---------------------------------------------------------------------------
  2693. DUSER_API BOOL WINAPI
  2694. GetTransitionInterface(HTRANSITION htrx, IUnknown ** ppUnk)
  2695. {
  2696. Transition * ptrx;
  2697. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  2698. VALIDATE_TRANSITION(trx);
  2699. VALIDATE_WRITE_PTR(ppUnk);
  2700. retval = ptrx->GetInterface(ppUnk);
  2701. END_RECV();
  2702. }
  2703. //---------------------------------------------------------------------------
  2704. DUSER_API BOOL WINAPI
  2705. BeginTransition(HTRANSITION htrx, const GTX_PLAY * pgx)
  2706. {
  2707. Transition * ptrx;
  2708. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2709. VALIDATE_TRANSITION(trx);
  2710. VALIDATE_READ_PTR_(pgx, sizeof(GTX_PLAY));
  2711. retval = ptrx->Begin(pgx);
  2712. END_RECV();
  2713. }
  2714. //---------------------------------------------------------------------------
  2715. DUSER_API BOOL WINAPI
  2716. PrintTransition(HTRANSITION htrx, float fProgress)
  2717. {
  2718. Transition * ptrx;
  2719. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2720. VALIDATE_TRANSITION(trx);
  2721. retval = ptrx->Print(fProgress);
  2722. END_RECV();
  2723. }
  2724. //---------------------------------------------------------------------------
  2725. DUSER_API BOOL WINAPI
  2726. EndTransition(HTRANSITION htrx, const GTX_PLAY * pgx)
  2727. {
  2728. Transition * ptrx;
  2729. BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer);
  2730. VALIDATE_TRANSITION(trx);
  2731. VALIDATE_READ_PTR_(pgx, sizeof(GTX_PLAY));
  2732. retval = ptrx->End(pgx);
  2733. END_RECV();
  2734. }
  2735. //---------------------------------------------------------------------------
  2736. DUSER_API HACTION WINAPI
  2737. CreateAction(const GMA_ACTION * pma)
  2738. {
  2739. BEGIN_RECV(HACTION, NULL, ContextLock::edNone);
  2740. VALIDATE_READ_STRUCT(pma, GMA_ACTION);
  2741. retval = GdCreateAction(pma);
  2742. END_RECV();
  2743. }
  2744. //---------------------------------------------------------------------------
  2745. DUSER_API BOOL WINAPI
  2746. GetActionTimeslice(DWORD * pdwTimeslice)
  2747. {
  2748. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  2749. VALIDATE_WRITE_PTR(pdwTimeslice);
  2750. *pdwTimeslice = GetMotionSC()->GetTimeslice();
  2751. retval = TRUE;
  2752. END_RECV();
  2753. }
  2754. //---------------------------------------------------------------------------
  2755. DUSER_API BOOL WINAPI
  2756. SetActionTimeslice(DWORD dwTimeslice)
  2757. {
  2758. BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
  2759. GetMotionSC()->SetTimeslice(dwTimeslice);
  2760. retval = TRUE;
  2761. END_RECV();
  2762. }
  2763. /***************************************************************************\
  2764. *****************************************************************************
  2765. *
  2766. * DirectUser UTIL API
  2767. *
  2768. * <package name="Util"/>
  2769. *
  2770. *****************************************************************************
  2771. \***************************************************************************/
  2772. //---------------------------------------------------------------------------
  2773. DUSER_API COLORREF WINAPI
  2774. GetStdColorI(UINT c)
  2775. {
  2776. BEGIN_RECV_NOCONTEXT(COLORREF, RGB(0, 0, 0));
  2777. VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
  2778. retval = GdGetColorInfo(c)->GetColorI();
  2779. END_RECV_NOCONTEXT();
  2780. }
  2781. //---------------------------------------------------------------------------
  2782. DUSER_API Gdiplus::Color WINAPI
  2783. GetStdColorF(UINT c)
  2784. {
  2785. BEGIN_RECV_NOCONTEXT(Gdiplus::Color, Gdiplus::Color((Gdiplus::ARGB) Gdiplus::Color::Black));
  2786. VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
  2787. retval = GdGetColorInfo(c)->GetColorF();
  2788. END_RECV_NOCONTEXT();
  2789. }
  2790. //---------------------------------------------------------------------------
  2791. DUSER_API HBRUSH WINAPI
  2792. GetStdColorBrushI(UINT c)
  2793. {
  2794. BEGIN_RECV(HBRUSH, NULL, ContextLock::edNone);
  2795. VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
  2796. retval = GetMotionSC()->GetBrushI(c);
  2797. END_RECV();
  2798. }
  2799. //---------------------------------------------------------------------------
  2800. DUSER_API Gdiplus::Brush * WINAPI
  2801. GetStdColorBrushF(UINT c)
  2802. {
  2803. BEGIN_RECV(Gdiplus::Brush *, NULL, ContextLock::edNone);
  2804. VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
  2805. retval = GetMotionSC()->GetBrushF(c);
  2806. END_RECV();
  2807. }
  2808. //---------------------------------------------------------------------------
  2809. DUSER_API HPEN WINAPI
  2810. GetStdColorPenI(UINT c)
  2811. {
  2812. BEGIN_RECV(HPEN, NULL, ContextLock::edNone);
  2813. VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
  2814. retval = GetMotionSC()->GetPenI(c);
  2815. END_RECV();
  2816. }
  2817. //---------------------------------------------------------------------------
  2818. DUSER_API Gdiplus::Pen * WINAPI
  2819. GetStdColorPenF(UINT c)
  2820. {
  2821. BEGIN_RECV(Gdiplus::Pen *, NULL, ContextLock::edNone);
  2822. VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
  2823. retval = GetMotionSC()->GetPenF(c);
  2824. END_RECV();
  2825. }
  2826. //---------------------------------------------------------------------------
  2827. DUSER_API LPCWSTR WINAPI
  2828. GetStdColorName(UINT c)
  2829. {
  2830. BEGIN_RECV_NOCONTEXT(LPCWSTR, NULL);
  2831. VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
  2832. retval = GdGetColorInfo(c)->GetName();
  2833. END_RECV_NOCONTEXT();
  2834. }
  2835. //---------------------------------------------------------------------------
  2836. DUSER_API UINT WINAPI
  2837. FindStdColor(LPCWSTR pszName)
  2838. {
  2839. BEGIN_RECV_NOCONTEXT(UINT, SC_Black);
  2840. VALIDATE_STRINGW_PTR(pszName, 50);
  2841. retval = GdFindStdColor(pszName);
  2842. END_RECV_NOCONTEXT();
  2843. }
  2844. //---------------------------------------------------------------------------
  2845. DUSER_API HPALETTE WINAPI
  2846. GetStdPalette()
  2847. {
  2848. BEGIN_RECV_NOCONTEXT(HPALETTE, NULL);
  2849. retval = GdGetStdPalette();
  2850. END_RECV_NOCONTEXT();
  2851. }
  2852. //---------------------------------------------------------------------------
  2853. DUSER_API BOOL WINAPI
  2854. UtilSetBackground(HGADGET hgadChange, HBRUSH hbrBack)
  2855. {
  2856. BOOL fSuccess = FALSE;
  2857. if (SetGadgetFillI(hgadChange, hbrBack, BLEND_OPAQUE, 0, 0)) {
  2858. UINT nStyle = hbrBack != NULL ? GS_OPAQUE : 0;
  2859. fSuccess = SetGadgetStyle(hgadChange, nStyle, GS_OPAQUE);
  2860. }
  2861. return fSuccess;
  2862. }
  2863. //---------------------------------------------------------------------------
  2864. DUSER_API HFONT WINAPI
  2865. UtilBuildFont(LPCWSTR pszName, int idxDeciSize, DWORD nFlags, HDC hdcDevice)
  2866. {
  2867. return GdBuildFont(pszName, idxDeciSize, nFlags, hdcDevice);
  2868. }
  2869. //---------------------------------------------------------------------------
  2870. DUSER_API BOOL WINAPI
  2871. UtilDrawBlendRect(HDC hdcDest, const RECT * prcDest, HBRUSH hbrFill, BYTE bAlpha, int wBrush, int hBrush)
  2872. {
  2873. return GdDrawBlendRect(hdcDest, prcDest, hbrFill, bAlpha, wBrush, hBrush);
  2874. }
  2875. //---------------------------------------------------------------------------
  2876. DUSER_API BOOL WINAPI
  2877. UtilDrawOutlineRect(HDC hdc, const RECT * prcPxl, HBRUSH hbrDraw, int nThickness)
  2878. {
  2879. return GdDrawOutlineRect(hdc, prcPxl, hbrDraw, nThickness);
  2880. }
  2881. //---------------------------------------------------------------------------
  2882. DUSER_API COLORREF WINAPI
  2883. UtilGetColor(HBITMAP hbmp, POINT * pptPxl)
  2884. {
  2885. return GdGetColor(hbmp, pptPxl);
  2886. }
  2887. /***************************************************************************\
  2888. *
  2889. * GetGadgetTicket
  2890. *
  2891. * The GetGadgetTicket function returns the ticket that can be used to
  2892. * identify the specified gadget.
  2893. *
  2894. * <param name="hgad">
  2895. * A handle to the gadget to retrieve the ticket for.
  2896. * </param>
  2897. *
  2898. * <return type="DWORD">
  2899. * If the function succeeds, the return value is a 32-bit ticket that
  2900. * can be used to identify the specified gadget.
  2901. * If the function fails, the return value is zero.
  2902. * </return>
  2903. *
  2904. * <remarks>
  2905. * Tickets are created to give an external identity to a gadget. A
  2906. * is guaranteed to be 32 bits on all platforms. If no ticket is
  2907. * currently associated with this gadget, one is allocated.
  2908. * </remarks>
  2909. *
  2910. * <see type="function">LookupGadgetTicket</>
  2911. *
  2912. \***************************************************************************/
  2913. DUSER_API DWORD WINAPI
  2914. GetGadgetTicket(
  2915. IN HGADGET hgad) // Handle of Gadget
  2916. {
  2917. DuVisual * pgad;
  2918. DWORD dwTicket;
  2919. HRESULT hr;
  2920. BEGIN_RECV(DWORD, 0, ContextLock::edNone);
  2921. VALIDATE_VISUAL(gad);
  2922. hr = pgad->GetTicket(&dwTicket);
  2923. SET_RETURN(hr, dwTicket);
  2924. END_RECV();
  2925. }
  2926. /***************************************************************************\
  2927. *
  2928. * LookupGadgetTicket
  2929. *
  2930. * The LookupGadgetTicket function returns the gadget that is associated with
  2931. * the specified ticket.
  2932. *
  2933. * <param name="dwTicket">
  2934. * A ticket that has been associated with a gadget via the
  2935. * GetGadgetTicket function.
  2936. * </param>
  2937. *
  2938. * <return type="HGADGET">
  2939. * If the function succeeds, the return value is a handle to the gadget
  2940. * associated with the ticket.
  2941. * If the function fails, the return value is NULL.
  2942. * </return>
  2943. *
  2944. * <see type="function">GetGadgetTicket</>
  2945. *
  2946. \***************************************************************************/
  2947. DUSER_API HGADGET WINAPI
  2948. LookupGadgetTicket(
  2949. IN DWORD dwTicket) // Ticket
  2950. {
  2951. BEGIN_RECV(HGADGET, NULL, ContextLock::edNone);
  2952. retval = DuVisual::LookupTicket(dwTicket);
  2953. END_RECV();
  2954. }