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.

430 lines
13 KiB

  1. pushdef(_prediv,divnum)divert(-1)dnl Redirect output to /dev/null for now
  2. changecom(`|')
  3. |
  4. | M4 macros for munging dinput.w
  5. | If you change dimkhdr.m4, remember to mirror \nt\private\windows\inc\dimkhdr.m4
  6. |
  7. | begindoc / enddoc
  8. |
  9. | everything between begindoc and enddoc is ignored. They are in the .w
  10. | file so that autodoc can extract the documentation.
  11. |
  12. define(`begindoc',`divert(-1)dnl')
  13. define(`enddoc',`divert('_prediv`)dnl')
  14. |
  15. | Internal macros which persist outside a begin_interface / end_interface
  16. | begin with _ so that they won't collide with words that happen to
  17. | appear in dinput.w
  18. |
  19. | Yeah, it isn't foolproof, but it's close enough for now.
  20. |
  21. |-----------------------------------------------------------------------------
  22. |
  23. | _Quote quotes its argument
  24. |
  25. define(`_Quote', `$@')
  26. |-----------------------------------------------------------------------------
  27. |
  28. | strsubst performs a search-and-replace on its argument
  29. |
  30. | First, the helper functions...
  31. |
  32. | strsubst__ -- Performs one found substitution, or stops
  33. |
  34. | $1 = processed source string (don't rescan)
  35. | $2 = unprocessed source string
  36. | $3 = old
  37. | $4 = new
  38. | $5 = location where `old' was found in $1, or -1 if stop
  39. |
  40. define(`strsubst__',
  41. `ifelse($5,-1,`$1$2',
  42. `strsubst_(`$1'_Quote(substr(`$2',0,$5))`$4',
  43. _Quote(substr(`$2',eval($5+len(`$3')))),
  44. `$3',`$4')')')
  45. | strsubst_ -- Try to perform one substitution, or stop
  46. |
  47. | $1 = processed source string (don't rescan)
  48. | $2 = unprocessed source string
  49. | $3 = old
  50. | $4 = new
  51. |
  52. define(`strsubst_', `strsubst__(`$1',`$2',`$3',`$4',index(`$2',`$3'))')
  53. | strsubst -- Perform a search-and-replace
  54. |
  55. | $1 = source string
  56. | $2 = old
  57. | $3 = new
  58. define(`strsubst', `strsubst_(`',`$1',`$2',`$3')')
  59. |-----------------------------------------------------------------------------
  60. |
  61. | uppercase converts a string to uppercase
  62. |
  63. define(`uppercase',
  64. `translit(`$1', `abcdefghijklmnopqrstuvwxyz',
  65. `ABCDEFGHIJKLMNOPQRSTUVWXYZ')')
  66. |-----------------------------------------------------------------------------
  67. | Interface definition macros. It goes like this:
  68. |
  69. | begin_interface(IMumble%, IUnknown)
  70. | begin_methods
  71. | declare_method(DeleteFeedback,DWORD)
  72. | declare_method(EnumFeedback,LPDIENUMFEEDBACKPROC%, LPVOID)
  73. | end_methods
  74. | end_interface
  75. |
  76. | (Actually, the second parameter to begin_interface is assumed
  77. | to be IUnknown if omitted.)
  78. |
  79. |
  80. | While an interface is being built:
  81. |
  82. | _itf contains the name of the interface
  83. | _itfP contains the name of the interface, sans % sign
  84. | _itfBase contains the name of the base interface
  85. | _itfBase{ contains the name of the base interface, sans % sign
  86. | _ucP contains an uppercase version of _itfP, sans leading `I'
  87. | _cset contains the current character set (W or A)
  88. |
  89. | _methods contains a list of the methods, in the form
  90. |
  91. | _invoke_(RETVAL,Method1,arg1,arg2)_invoke_(RETVAL,Method2,arg1,arg2)...
  92. |
  93. | except that you might find an _invoke2_() inserted when the
  94. | base class methods disappear and the extended methods emerge.
  95. |
  96. | declare_method takes a variable number of parameters. The first
  97. | is the method name. The rest are method argument types.
  98. |
  99. | declare_method_ is like declare_method, except you can override
  100. | the return value.
  101. |
  102. define(`begin_interface',`pushdef(`_itf',`$1')'dnl
  103. `pushdef(`_itfBase', ifelse(`$2',`', `IUnknown', `$2'))dnl')
  104. define(`begin_methods',
  105. `pushdef(`_methods',
  106. `_invoke2_(ifelse(_itfBase, `IUnknown', `_itf', `_itfBase'))')dnl')
  107. define(`declare_method_',
  108. `define(`_methods',defn(`_methods')`_invoke_($*)')dnl')
  109. define(`declare_method', `declare_method_(HRESULT,$*)')
  110. define(`end_base_class_methods',
  111. `define(`_methods',defn(`_methods')`_invoke2_(_itf)')dnl')
  112. define(`end_methods',`_emit_methods`'popdef(`_methods')dnl')
  113. define(`end_interface',`popdef(`_itf')dnl')
  114. |-----------------------------------------------------------------------------
  115. |
  116. | _invoke_per_method calls its argument macro once for each method.
  117. |
  118. | Optional second argument handles _invoke2_'s.
  119. |
  120. define(`_invoke_per_method',
  121. `pushdef(`_invoke_', defn(`$1'))'dnl
  122. `pushdef(`_invoke2_', ifelse(`$2', `', `', defn(`$2')))'dnl
  123. `_methods`'popdef(`_invoke_')popdef(`_invoke2_')')
  124. |-----------------------------------------------------------------------------
  125. |
  126. | _DePercent
  127. |
  128. | Remove percent signs by turning TSTR% into WSTR/STR and other %'s
  129. | into W or A. Turning TSTR% into WSTR/STR is a hack: We have more
  130. | macros that map symbols like LPTSTRW -> LPWSTR.
  131. |
  132. | $1 - W or A
  133. | $2... - the thing to change
  134. |
  135. define(`_DePercent', `translit(`$2', `%', `$1')')
  136. define(`LPTSTRW', `LPWSTR')
  137. define(`LPTSTRA', `LPSTR')
  138. define(`LPCTSTRW', `LPCWSTR')
  139. define(`LPCTSTRA', `LPCSTR')
  140. |-----------------------------------------------------------------------------
  141. |
  142. | _DoItf emits a single interface definition in the appropriate
  143. | character set.
  144. |
  145. | $1 - character set (A or W)
  146. | _itf - temporarily redefined to the de-percentified name
  147. | _TF - interface name uppercased, without the leading "I"
  148. |
  149. define(`_DoItf',
  150. `pushdef(`_cset', `$1')'dnl
  151. `pushdef(`_itf', _DePercent(`$1', _itf))'dnl
  152. `pushdef(`_itfBase', _DePercent(`$1', _itfBase))'dnl
  153. `pushdef(`_TF', uppercase(substr(_itf, 1)))'dnl
  154. `#undef INTERFACE
  155. `#'define INTERFACE _itf
  156. DECLARE_INTERFACE_(_itf, _itfBase)
  157. {
  158. /*** IUnknown methods ***/
  159. STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
  160. STDMETHOD_(ULONG,AddRef)(THIS) PURE;
  161. STDMETHOD_(ULONG,Release)(THIS) PURE;
  162. _invoke_per_method(`_emit_method_definition', `_emit_class_header')};
  163. typedef struct _itf *LP`'_TF;
  164. popdef(`_TF')popdef(`_itf')popdef(`_itfBase')popdef(`_cset')')
  165. |-----------------------------------------------------------------------------
  166. |
  167. | _emit_method_definition
  168. |
  169. | Called once for each method. Generates the STDMETHOD() line.
  170. |
  171. | $1 - return type (usually HRESULT)
  172. | $2 - method name
  173. | $3 - arguments
  174. |
  175. | If the return type is HRESULT, then use STDMETHOD. Otherwise,
  176. | use STDMETHOD_.
  177. |
  178. | If there are no arguments, then use THIS. Otherwise, use THIS_.
  179. |
  180. define(`_emit_method_definition',
  181. `_DePercent(_cset,
  182. ifelse($1,HRESULT,
  183. ` STDMETHOD($2)',
  184. ` STDMETHOD_($1,$2)')`(ifelse($#,2, THIS,
  185. `_Quote(THIS_ shift(shift($*)))')) PURE;
  186. ')')
  187. |-----------------------------------------------------------------------------
  188. |
  189. | _emit_class_header
  190. |
  191. | Called once for each change of class. Generates a happy comment block.
  192. |
  193. define(`_emit_class_header',
  194. `
  195. /*** $1 methods ***/
  196. ')
  197. |-----------------------------------------------------------------------------
  198. |
  199. | _DoAfterItfVariation
  200. |
  201. | Emit $1, first as W, then as A.
  202. |
  203. define(`_DoAfterItfVariation',
  204. `#ifdef UNICODE
  205. _DePercent(`W', `$*')
  206. #else
  207. _DePercent(`A', `$*')
  208. #endif')
  209. |-----------------------------------------------------------------------------
  210. |
  211. | _DoAfterItf emits the follow-up stuff that comes after an interface
  212. | definition. If the interface name contains a percent sign, emit
  213. | the appropriate mix.
  214. |
  215. define(`_DoAfterItf',
  216. `ifelse(_itf, _itfP,, `_DoAfterItfVariation(
  217. `#'define IID_`'_itfP IID_`'_itf
  218. `#'define _itfP _itf
  219. `#'define _itfP`'Vtbl _itf`'Vtbl)
  220. typedef struct _itfP *LP`'_ucP;
  221. ')#if !defined(__cplusplus) || defined(CINTERFACE)
  222. _EmitWrapper(HRESULT, `QueryInterface', REFIID riid, LPVOID * ppvObj)'dnl
  223. `_EmitWrapper(ULONG, `AddRef')'dnl
  224. `_EmitWrapper(ULONG, `Release')'dnl
  225. `_invoke_per_method( `_EmitWrapper')#else
  226. _EmitCPPWrapper(HRESULT, `QueryInterface', REFIID riid, LPVOID * ppvObj)'dnl
  227. `_EmitCPPWrapper(ULONG, `AddRef')'dnl
  228. `_EmitCPPWrapper(ULONG, `Release')'dnl
  229. `_invoke_per_method( `_EmitCPPWrapper')#endif
  230. ')
  231. |-----------------------------------------------------------------------------
  232. |
  233. | _Arity - generate fake arguments based on arity
  234. |
  235. | What comes out is "Method(p,a,b,c)" if arity is 4
  236. |
  237. | Note that we skip `p' in the alphabetical list. Duh.
  238. |
  239. | $1 = method
  240. | $2 = number of arguments (including method itself and return value)
  241. |
  242. define(`_Arity',
  243. `$1(substr(`p,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,q,r,s,t,u,v,w,x,y,z',
  244. 0, eval($2 * 2 - 3)))')
  245. |-----------------------------------------------------------------------------
  246. |
  247. | _ArityCPP - generate fake arguments based on arity
  248. |
  249. | What comes out is "Method(a,b,c)" if arity is 4 (we ate the `p')
  250. |
  251. | Note that we skip `p' in the alphabetical list. Duh.
  252. |
  253. | Note also that we need to special-case the situation where
  254. | the arity is exactly zero, so we don't underflow.
  255. |
  256. | $1 = method
  257. | $2 = number of arguments (including method itself and return value)
  258. |
  259. define(`_ArityCPP',
  260. `$1(ifelse($2,2,,`substr(`a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,q,r,s,t,u,v,w,x,y,z',
  261. 0, eval($2 * 2 - 5))'))')
  262. |-----------------------------------------------------------------------------
  263. |
  264. | _EmitWrapper - generate a wrapper macro
  265. |
  266. | _itfP - interface name without % sign
  267. | $1 - return value name
  268. | $2 - method name
  269. | $3... - other arguments
  270. |
  271. define(`_EmitWrapper',
  272. ``#'define _itfP`'_`'_Arity($2,$#) (p)->lpVtbl->_Arity($2,$#)
  273. ')
  274. |-----------------------------------------------------------------------------
  275. |
  276. | _EmitCPPWrapper - generate a C++ wrapper macro
  277. |
  278. | _itfP - interface name without % sign
  279. | $1 - return value name
  280. | $2 - method name
  281. | $3... - other arguments
  282. |
  283. define(`_EmitCPPWrapper',
  284. ``#'define _itfP`'_`'_Arity($2,$#) (p)->_ArityCPP($2,$#)
  285. ')
  286. |-----------------------------------------------------------------------------
  287. |
  288. | The long-awaited _emit_methods, which drives all the real work.
  289. |
  290. |
  291. |define(`emit_methods', `invoke_per_method(`_DoItf')')
  292. define(`_emit_methods',
  293. `pushdef(`_itfP', translit(_itf, `%'))'dnl
  294. `pushdef(`_ucP', uppercase(substr(_itfP, 1)))'dnl
  295. `ifelse(index(_itf, `%'), -1, `_DoItf(`W')',
  296. `_DoItf(`W')_DoItf(`A')')'dnl
  297. `_DoAfterItf()popdef(`_ucP')popdef(`_itfP')')
  298. |-----------------------------------------------------------------------------
  299. |
  300. | dik_define - remember the definition as an m4 macro before spitting it out
  301. define(`dik_def', `define(strsubst(`_$1',` '),$2)`#'define `$1' $2')
  302. |-----------------------------------------------------------------------------
  303. |
  304. | Message cracker definition macros. It goes like this:
  305. |
  306. | begin_message_cracker(DIDM_,IDirectInputDeviceCallback *,this,CDIDev)
  307. | message_cracker(Acquire,HANDLE,hevt)
  308. | message_cracker(GetDataFormat,,,LPDIDATAFORMAT,pdidf)
  309. | end_message_cracker()
  310. |
  311. |-----------------------------------------------------------------------------
  312. |
  313. | _ifnb - macro which emits its second argument if the first is nonblank
  314. define(`_ifnb', `ifelse(`$1',,,`$2')')
  315. |-----------------------------------------------------------------------------
  316. |
  317. | begin_message_cracker - Begin a set of message crackers
  318. |
  319. | $1 - prefix for messages
  320. | $2 - type of first parameter
  321. | $3 - name of first parameter
  322. | $4 - type of parent object
  323. |
  324. | For example, Windows messages would be
  325. |
  326. | begin_message_cracker(WM_,HWND,hwnd,?)
  327. |
  328. | IDirectInputDeviceCallback would be
  329. |
  330. | begin_message_cracker(DIDM_,IDirectInputDeviceCallback *,this,CDIDev)
  331. |
  332. | Variables used during message cracker macro generation:
  333. |
  334. | _prefix - the prefix for the message
  335. | _type1 - type of the first argument
  336. | _name1 - name of the first argument
  337. | _ptype1 - type of parent object
  338. |
  339. define(`begin_message_cracker',
  340. `pushdef(`_prefix',`$1')'dnl
  341. `pushdef(`_type1',`$2')'dnl
  342. `pushdef(`_name1',`$3')'dnl
  343. `pushdef(`_ptype',`$4')'dnl
  344. `HRESULT NTAPI;internal
  345. _ptype`'_CallDevice(struct _ptype *this, UINT didm, WPARAM wp, LPARAM lp);;internal
  346. ')
  347. define(`end_message_cracker',
  348. `popdef(`_prefix')popdef(`_type1')popdef(`_name1')popdef(`_ptype')')
  349. |-----------------------------------------------------------------------------
  350. |
  351. | message_cracker
  352. |
  353. | $1 - name of message, mixed-case.
  354. | $2 - type of wParam, or null if wParam is ignored
  355. | $3 - name of wParam, or null if wParam is ignored
  356. | $4 - type of lParam, or null if lParam is ignored
  357. | $5 - name of lParam, or null if lParam is ignored
  358. |
  359. | Local variable:
  360. |
  361. | _uc - uppercase version of $1 with _prefix attached
  362. define(`message_cracker',
  363. `pushdef(`_uc', _prefix`'uppercase(`$1'))'dnl
  364. `/*
  365. * HRESULT Cls_On$1('dnl
  366. `_ifnb(`$2$4',`
  367. * ')_type1 _name1`'_ifnb(`$2',`, $2 $3`'')_ifnb(`$4',`, $4 $5'))
  368. */
  369. `#'define HANDLE_`'_uc`'(_name1, wParam, lParam, fn) \
  370. ((fn)((_name1)'dnl
  371. `_ifnb(`$2',`, ($2)(wParam)')'dnl
  372. `_ifnb(`$4',`, ($4)(lParam)')'dnl
  373. `))
  374. `#'define FORWARD_`'_uc`'(_name1`''dnl
  375. `_ifnb(`$2',`, $3`'')'dnl
  376. `_ifnb(`$4',`, $5'), fn) \
  377. ((fn)(_name1, _uc, 'dnl
  378. `ifelse(`$2',,0,`(WPARAM)($3)'), 'dnl
  379. `ifelse(`$4',,0,`(LPARAM)($5)')))
  380. HRESULT static __inline
  381. dcb$1(struct _ptype *this`'_ifnb(`$2',`, $2 $3`'')_ifnb(`$4',`, $4 $5'))
  382. {
  383. return FORWARD_`'_uc`'(this`'_ifnb(`$2',`, $3`'')_ifnb(`$4',`, $5'),'dnl
  384. ` _ptype`'_CallDevice);
  385. }
  386. ')
  387. |-----------------------------------------------------------------------------
  388. | Restore comments and the previous diversion
  389. changecom()
  390. divert(_prediv)popdef(`_prediv')dnl End of macro header file