Source code of Windows XP (NT5)
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.

305 lines
6.9 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: loghot.cxx
  3. *
  4. * Copyright (c) 1997 Microsoft Corporation
  5. *
  6. \**************************************************************************/
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include <sys/types.h>
  11. #include <stdlib.h>
  12. #include <time.h>
  13. #include "logon.hxx"
  14. #include "resource.h"
  15. static LOG_OBJECT *pHotObj;
  16. static void DrawBanner();
  17. static BOOL bFrameObjects; // whether to frame the objects or not
  18. static float colorHot[3] = { 0.0f, 1.0f, 0.0f };
  19. static float colorWhite[3] = { 1.0f, 1.0f, 1.0f };
  20. #define HOT_CURSOR 1
  21. /******************** HOT SEQUENCE ****************************************\
  22. *
  23. \**************************************************************************/
  24. static LOG_OBJECT*
  25. CheckForHit( int mouseX, int mouseY )
  26. {
  27. // Check mouse coords against rect of each object. Return ptr to object
  28. // if within.
  29. mouseY = InvertY( mouseY, winSize.height );
  30. LOG_OBJECT *pObj;
  31. GLIRECT rect, *pRect;
  32. pRect = &rect;
  33. for( int i = 0; i < nLogObj; i++ ) {
  34. pObj = pLogObj[i];
  35. pObj->GetRect( pRect );
  36. if( ( mouseX >= pRect->x ) &&
  37. ( mouseX < (pRect->x + pRect->width) ) &&
  38. ( mouseY >= pRect->y ) &&
  39. ( mouseY < (pRect->y + pRect->height) ) )
  40. {
  41. // SS_DBGPRINT( "CheckForHit() recording a hit\n" );
  42. return pObj;
  43. }
  44. }
  45. return NULL;
  46. }
  47. static void
  48. DrawObject( LOG_OBJECT *pObj, BOOL bHot )
  49. {
  50. if( !pObj )
  51. return;
  52. // Set ColorMaterial color, in case lighting is on for the frame
  53. if( bHot ) {
  54. glColor3fv( colorHot );
  55. } else {
  56. glColor3fv( colorWhite );
  57. }
  58. pObj->Draw();
  59. }
  60. // This redraws everything
  61. static void DrawHotSequence(void)
  62. {
  63. ClearWindow();
  64. LOG_OBJECT *pObj;
  65. for( int i = 0; i < nLogObj; i++ ) {
  66. pObj = pLogObj[i];
  67. DrawObject( pObj, (pObj == pHotObj) );
  68. }
  69. Flush();
  70. DrawBanner();
  71. }
  72. static void
  73. FinishLogonHotSequence()
  74. {
  75. #ifndef HOT_CURSOR
  76. // User has selected an object.
  77. // Turn off hilite on current selection and return
  78. DrawObject( pHotObj, FALSE );
  79. Flush();
  80. #endif
  81. mtkWin->Return();
  82. }
  83. static BOOL
  84. HotKey(int key, GLenum mask)
  85. {
  86. switch (key) {
  87. case TK_RETURN:
  88. if( pHotObj )
  89. FinishLogonHotSequence();
  90. break;
  91. case TK_ESCAPE:
  92. if( bDebugMode )
  93. Quit();
  94. break;
  95. case TK_SPACE:
  96. if( bDebugMode ) {
  97. bRunAgain = TRUE;
  98. FinishLogonHotSequence();
  99. }
  100. break;
  101. default:
  102. if( bDebugMode )
  103. return AttributeKey( key, mask );
  104. return FALSE;
  105. }
  106. return FALSE;
  107. }
  108. static BOOL
  109. MouseButton(int mouseX, int mouseY, GLenum button)
  110. {
  111. // If left button click on an object, run end of logon sequence
  112. if( !(button & TK_LEFTBUTTON) )
  113. return GL_FALSE;
  114. LOG_OBJECT *pObj;
  115. if( pObj = CheckForHit( mouseX, mouseY ) ) {
  116. pHotObj = pObj;
  117. FinishLogonHotSequence();
  118. }
  119. return FALSE;
  120. }
  121. static BOOL
  122. MouseMove(int mouseX, int mouseY, GLenum button)
  123. {
  124. // Handle a mouse move. Redraw only when necessary
  125. LOG_OBJECT *pObj;
  126. LOG_OBJECT *pLastHotObj = pHotObj;
  127. if( pObj = CheckForHit( mouseX, mouseY ) ) {
  128. if( pObj == pHotObj ) {
  129. // State has not changed
  130. return FALSE;
  131. }
  132. // New hot object
  133. pHotObj = pObj;
  134. SetCursor( hHotCursor );
  135. } else {
  136. SetCursor( hNormalCursor );
  137. if( !pHotObj ) {
  138. // State has not changed
  139. return FALSE;
  140. }
  141. // No hot object
  142. pHotObj = NULL;
  143. }
  144. #ifndef HOT_CURSOR
  145. if( ! bSwapHints )
  146. // Need to do complete redraw
  147. return TRUE;
  148. // Redraw only the objects that changed
  149. if( pLastHotObj ) {
  150. // remove hot indicator from old hot object
  151. DrawObject( pLastHotObj, FALSE );
  152. }
  153. if( pHotObj ) {
  154. // add hot indicator to new hot object
  155. DrawObject( pHotObj, TRUE );
  156. }
  157. // Flush the changes
  158. Flush();
  159. #endif
  160. return FALSE;
  161. }
  162. static void DrawBanner()
  163. {
  164. BitBlt( mtkWin->GetHdc(), 0, 0, bannerSize.width, bannerSize.height,
  165. hdcMem, 0, 0, SRCCOPY );
  166. GdiFlush();
  167. }
  168. LOG_OBJECT *
  169. RunLogonHotSequence()
  170. {
  171. if( bDebugMode )
  172. bRunAgain = FALSE;
  173. // Stop animation, make quads 'hot'
  174. SS_DBGPRINT( "RunLogonHotSequence()\n" );
  175. // If the objects were flown in without context their origins would have
  176. // been in centre of the image part. Since we want to add context now,
  177. // have to offset the destination values. This is done inside next loop
  178. // Calc window rects of the quads
  179. bSwapHints = bSwapHintsEnabled;
  180. UpdateLocalTransforms( UPDATE_ALL );
  181. bFrameObjects = FALSE; // no framing currently
  182. LOG_OBJECT *pObj;
  183. for( int i = 0; i < nLogObj; i++ ) {
  184. pObj = pLogObj[i];
  185. pObj->ShowContext( TRUE );
  186. if( !bFlyWithContext ) {
  187. // offset x dest value to the left (again, size assumption)
  188. pObj->OffsetDest( - OBJECT_WIDTH / 4.0f, 0.0f, 0.0f );
  189. }
  190. if( bFrameObjects )
  191. pObj->ShowFrame( TRUE );
  192. pObj->CalcWinRect();
  193. }
  194. pHotObj = NULL;
  195. // Set any gl attributes
  196. if( bFrameObjects ) {
  197. glEnable(GL_CULL_FACE);
  198. glEnable(GL_DEPTH_TEST);
  199. bDepth = TRUE;
  200. }
  201. // Go to slower but nicer texture drawing while in this mode
  202. for( i = 0; i < nLogObj; i++ ) {
  203. pLogObj[i]->pTex->MakeCurrent();
  204. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  205. }
  206. // Set up mtk functions for this sequence
  207. mtkWin->SetAnimateFunc( NULL );
  208. mtkWin->SetKeyDownFunc(HotKey);
  209. mtkWin->SetMouseMoveFunc( MouseMove );
  210. mtkWin->SetMouseDownFunc( MouseButton );
  211. mtkWin->SetDisplayFunc( DrawHotSequence );
  212. // Now get the current pointer position and simulate a mouse move with it,
  213. // in case it's over one of the objects.
  214. IPOINT2D ptMouse;
  215. mtkWin->GetMouseLoc( &ptMouse.x, &ptMouse.y );
  216. // Need to check that mouse is inside window
  217. if( (ptMouse.x >= 0) &&
  218. (ptMouse.x < winSize.width) &&
  219. (ptMouse.y >= 0) &&
  220. (ptMouse.y < winSize.height) )
  221. {
  222. MouseMove( ptMouse.x, ptMouse.y, 0 );
  223. }
  224. // Draw everything (so nicer textures show up)
  225. DrawHotSequence();
  226. if( !mtkWin->Exec() )
  227. return NULL;
  228. // Restore gl attributes
  229. for( i = 0; i < nLogObj; i++ ) {
  230. pLogObj[i]->pTex->MakeCurrent();
  231. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  232. }
  233. glDisable(GL_DEPTH_TEST);
  234. glDisable(GL_CULL_FACE);
  235. bDepth = FALSE;
  236. // Turn frames off for the objects
  237. for( i = 0; i < nLogObj; i++ ) {
  238. pLogObj[i]->ShowFrame( FALSE );
  239. }
  240. // Dump the cursor
  241. SetCursor( NULL );
  242. return pHotObj;
  243. }