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.

903 lines
26 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: sswproc.cxx
  3. *
  4. * Window procedure functions.
  5. *
  6. * Copyright (c) 1996 Microsoft Corporation
  7. \**************************************************************************/
  8. #include "mtk.hxx"
  9. #include "mtkinit.hxx"
  10. #include "palette.hxx"
  11. #include "clear.hxx"
  12. #include "mtkwproc.hxx"
  13. //mf: some of this stuff should be per window-group eventually
  14. SSW_TABLE sswTable;
  15. //mf: this needs to be per window group
  16. static BOOL bInBackground;
  17. // forward declarations of internal functions
  18. LONG SS_ScreenSaverProc( HWND, UINT, WPARAM, LPARAM );
  19. LONG MainPaletteManageProc(HWND, UINT, WPARAM, LPARAM );
  20. static LONG InputManageProc(HWND, UINT, WPARAM, LPARAM );
  21. static void ForceRedraw( HWND Window );
  22. static void ssw_RealizePalette( PMTKWIN pssw, BOOL bBackground );
  23. static void ssw_DeletePalette( PMTKWIN pssw );
  24. /**************************************************************************\
  25. * ScreenSaverProc
  26. *
  27. * Processes messages for the top level screen saver window.
  28. *
  29. * Unhandled msgs are sent to DefScreenSaverProc
  30. \**************************************************************************/
  31. LONG
  32. mtkWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  33. {
  34. HDC hdc;
  35. PAINTSTRUCT ps;
  36. MTKWIN *pmtkwin;
  37. switch (message)
  38. {
  39. case WM_CREATE:
  40. case WM_ERASEBKGND:
  41. return SS_ScreenSaverProc( hwnd, message, wParam, lParam);
  42. case WM_ACTIVATE:
  43. if ( LOWORD(wParam) == WA_INACTIVE ) {
  44. SS_DBGMSG( "Main_Proc: WM_ACTIVATE inactive\n" );
  45. bInBackground = TRUE;
  46. } else {
  47. SS_DBGMSG( "Main_Proc: WM_ACTIVATE active\n" );
  48. bInBackground = FALSE;
  49. }
  50. // fall thru
  51. case WM_QUERYNEWPALETTE:
  52. case WM_PALETTECHANGED:
  53. case WM_SYSCOLORCHANGE:
  54. case MTK_WM_PALETTE:
  55. return( MainPaletteManageProc( hwnd, message, wParam, lParam ) );
  56. case WM_DESTROY:
  57. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  58. if( ! pmtkwin ) {
  59. SS_WARNING( "WM_DESTROY : pmtkwin is NULL\n" );
  60. return 0;
  61. }
  62. //mf: Before deleting this top level window, we need to use its
  63. // still-valid dc to things like restore SystemPaletteUse mode. Ideally this
  64. // should be done after ~SSW has dumped GL, but ~SSW also releases the DC.
  65. // If this is a problem, we can create a new function SSW::DeleteGL that just
  66. // gets rid of the GL part
  67. if( sswTable.GetNumWindows() == 1 ) {
  68. // This is the last window, special considerations
  69. // Handle any palette stuff
  70. if( gpssPal )
  71. ssw_DeletePalette( pmtkwin );
  72. delete pmtkwin;
  73. // All win's have now been deleted - remove global ptr to top of
  74. // window chain.
  75. gpMtkwinMain = NULL;
  76. }
  77. // mf: ! this kills the app !, that's not what we want...
  78. // Doesn't seem to make much of a difference if call it or not
  79. // PostQuitMessage(0);
  80. return 0;
  81. case WM_PAINT:
  82. SS_DBGMSG( "mtkWndProc: WM_PAINT\n" );
  83. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  84. pmtkwin->Repaint( TRUE );
  85. #ifdef SS_DO_PAINT
  86. // We do the painting rather than letting the system do it
  87. hdc = BeginPaint(hwnd, &ps);
  88. // This is case where bg brush is NULL and we have to do repaint
  89. // We only do it after bInited, as this will avoid the first
  90. // -> bInited removed 5/1/97
  91. // WM_PAINT for the entire window.
  92. DrawGdiRect( hdc, ghbrBg, &ps.rcPaint );
  93. EndPaint(hwnd, &ps);
  94. return 0; // painting has been handled by us
  95. #endif // SS_DO_PAINT
  96. break;
  97. case MTK_WM_REDRAW:
  98. SS_DBGMSG( "mtkWndProc: MTK_WM_REDRAW\n" );
  99. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  100. pmtkwin->Display();
  101. return 0;
  102. case WM_MOVE:
  103. SS_DBGMSG( "mtkWndProc: WM_MOVE\n" );
  104. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  105. pmtkwin->pos.x = LOWORD(lParam);
  106. pmtkwin->pos.y = HIWORD(lParam);
  107. break;
  108. //mf
  109. #if 1
  110. // This allows us to pick up under-bits on window moves
  111. case WM_WINDOWPOSCHANGING:
  112. {
  113. LPWINDOWPOS lpwp = (LPWINDOWPOS) lParam;
  114. SS_DBGMSG1( "mtkWndProc: WM_WINDOWPOSCHANGING, flags = %x\n",
  115. lpwp->flags );
  116. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  117. if( pmtkwin->pBackgroundBitmap ) {
  118. #if 0
  119. // If window moving, don't want to copy old bits...
  120. //mf: this actually fukin works (sometimes) !
  121. if( !(lpwp->flags & SWP_NOMOVE) ) {
  122. SS_DBGMSG( "mtkWndProc: WM_WINDOWPOSCHANGING, moving\n" );
  123. // window moving
  124. if( !(lpwp->flags & SWP_NOCOPYBITS) ) {
  125. lpwp->flags |= SWP_NOCOPYBITS;
  126. }
  127. }
  128. }
  129. #else
  130. // Things seem to work better if we always force this flag, otherwise now
  131. // and then get partial update rects, even if window active and moving (in
  132. // which case update rect should always be entire client area.
  133. lpwp->flags |= SWP_NOCOPYBITS;
  134. }
  135. #endif
  136. }
  137. break;
  138. case WM_WINDOWPOSCHANGED:
  139. {
  140. LPWINDOWPOS lpwp = (LPWINDOWPOS) lParam;
  141. SS_DBGMSG1( "mtkWndProc: WM_WINDOWPOSCHANGED, flags = %x\n",
  142. lpwp->flags );
  143. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  144. if( pmtkwin->pBackgroundBitmap ) {
  145. if( !(lpwp->flags & SWP_NOMOVE) ) {
  146. // window moved
  147. // SS_DBGMSG( "mtkWndProc: WM_WINDOWPOSCHANGED, moved\n" );
  148. }
  149. }
  150. }
  151. break;
  152. #endif
  153. case WM_TIMER:
  154. SS_DBGMSG( "mtkWndProc: WM_TIMER\n" );
  155. if( pmtkwin = sswTable.PsswFromHwnd( hwnd ) )
  156. pmtkwin->mtkAnimate();
  157. return 0;
  158. }
  159. //mf: for now...
  160. return SS_ScreenSaverProc(hwnd, message, wParam, lParam);
  161. }
  162. /**************************************************************************\
  163. * SS_ScreenSaverProc
  164. *
  165. * Wndproc for child windows, and some messages from top-level window
  166. *
  167. * Unhandled msgs are sent to DefWindowProc
  168. \**************************************************************************/
  169. LONG
  170. SS_ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  171. {
  172. HDC hdc;
  173. PAINTSTRUCT ps;
  174. int i;
  175. int retVal;
  176. MTKWIN *pmtkwin;
  177. switch (message)
  178. {
  179. case WM_CREATE:
  180. SS_DBGMSG1( "SS_Proc: WM_CREATE for 0x%x\n", hwnd );
  181. pmtkwin = (PMTKWIN) ( ((LPCREATESTRUCT)lParam)->lpCreateParams );
  182. sswTable.Register( hwnd, pmtkwin );
  183. pmtkwin->hwnd = hwnd;
  184. break;
  185. case MTK_WM_PALETTE:
  186. return( MainPaletteManageProc( hwnd, message, wParam, lParam ) );
  187. case WM_DESTROY:
  188. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  189. SS_DBGMSG1( "SS_Proc: WM_DESTROY for 0x%x\n", hwnd );
  190. // Delete the pssw - this does all necessary cleanup
  191. if( pmtkwin )
  192. delete pmtkwin;
  193. else
  194. SS_WARNING( "WM_DESTROY : pmtkwin is NULL\n" );
  195. break;
  196. case WM_PAINT:
  197. // We get this msg every time window moves, since SWP_NOCOPYBITS is
  198. // specified with the window move.
  199. hdc = BeginPaint(hwnd, &ps);
  200. //mf: will need to call DisplayFunc here...
  201. // -> currently being handled in tkWndProc
  202. EndPaint(hwnd, &ps);
  203. break;
  204. case WM_SIZE:
  205. SS_DBGMSG( "mtkWndProc: WM_SIZE\n" );
  206. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  207. // Suspend drawing if minimized
  208. if( wParam == SIZE_MINIMIZED ) {
  209. // Stop any animation
  210. pmtkwin->animator.Stop(); // noop if no timer
  211. // We can return here, since for now we don't do anything
  212. // in a minimized window
  213. return 0;
  214. }
  215. else { // either SIZE_RESTORED or SIZE_MAXIMIZED
  216. // If there is an animation func, restart animation
  217. //mf: potential problem here if timer was not started...
  218. pmtkwin->animator.Start();
  219. }
  220. pmtkwin->Resize( LOWORD(lParam), HIWORD(lParam) );
  221. break;
  222. // these msg's are never received by the child window ?
  223. case WM_ACTIVATE:
  224. case WM_QUERYNEWPALETTE:
  225. case WM_PALETTECHANGED:
  226. return( MainPaletteManageProc( hwnd, message, wParam, lParam ) );
  227. case WM_MOUSEMOVE:
  228. case WM_LBUTTONDOWN:
  229. case WM_MBUTTONDOWN:
  230. case WM_RBUTTONDOWN:
  231. case WM_LBUTTONUP:
  232. case WM_MBUTTONUP:
  233. case WM_RBUTTONUP:
  234. case WM_KEYDOWN:
  235. case WM_CHAR:
  236. //mf: this can be fn ptr eventually, so ss's can use it too
  237. return( InputManageProc( hwnd, message, wParam, lParam ) );
  238. default:
  239. return DefWindowProc(hwnd, message, wParam, lParam);
  240. }
  241. return 0;
  242. }
  243. /**************************************************************************\
  244. * InputManageProc
  245. *
  246. \**************************************************************************/
  247. static LONG
  248. InputManageProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  249. {
  250. MTKWIN *pmtkwin = sswTable.PsswFromHwnd( hWnd );
  251. int key;
  252. switch( message ) {
  253. case WM_MOUSEMOVE:
  254. if (pmtkwin->MouseMoveFunc)
  255. {
  256. GLenum mask;
  257. mask = 0;
  258. if (wParam & MK_LBUTTON) {
  259. mask |= TK_LEFTBUTTON;
  260. }
  261. if (wParam & MK_MBUTTON) {
  262. mask |= TK_MIDDLEBUTTON;
  263. }
  264. if (wParam & MK_RBUTTON) {
  265. mask |= TK_RIGHTBUTTON;
  266. }
  267. if ((*pmtkwin->MouseMoveFunc)( LOWORD(lParam), HIWORD(lParam), mask ))
  268. {
  269. ForceRedraw( hWnd );
  270. }
  271. }
  272. return (0);
  273. case WM_LBUTTONDOWN:
  274. SetCapture(hWnd);
  275. if (pmtkwin->MouseDownFunc)
  276. {
  277. if ( (*pmtkwin->MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  278. TK_LEFTBUTTON) )
  279. {
  280. ForceRedraw( hWnd );
  281. }
  282. }
  283. return (0);
  284. case WM_LBUTTONUP:
  285. ReleaseCapture();
  286. if (pmtkwin->MouseUpFunc)
  287. {
  288. if ((*pmtkwin->MouseUpFunc)(LOWORD(lParam), HIWORD(lParam), TK_LEFTBUTTON))
  289. {
  290. ForceRedraw( hWnd );
  291. }
  292. }
  293. return (0);
  294. case WM_MBUTTONDOWN:
  295. SetCapture(hWnd);
  296. if (pmtkwin->MouseDownFunc)
  297. {
  298. if ((*pmtkwin->MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  299. TK_MIDDLEBUTTON))
  300. {
  301. ForceRedraw( hWnd );
  302. }
  303. }
  304. return (0);
  305. case WM_MBUTTONUP:
  306. ReleaseCapture();
  307. if (pmtkwin->MouseUpFunc)
  308. {
  309. if ((*pmtkwin->MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  310. TK_MIDDLEBUTTON))
  311. {
  312. ForceRedraw( hWnd );
  313. }
  314. }
  315. return (0);
  316. case WM_RBUTTONDOWN:
  317. SetCapture(hWnd);
  318. if (pmtkwin->MouseDownFunc)
  319. {
  320. if ((*pmtkwin->MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  321. TK_RIGHTBUTTON))
  322. {
  323. ForceRedraw( hWnd );
  324. }
  325. }
  326. return (0);
  327. case WM_RBUTTONUP:
  328. ReleaseCapture();
  329. if (pmtkwin->MouseUpFunc)
  330. {
  331. if ((*pmtkwin->MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  332. TK_RIGHTBUTTON))
  333. {
  334. ForceRedraw( hWnd );
  335. }
  336. }
  337. return (0);
  338. case WM_KEYDOWN:
  339. switch (wParam) {
  340. case VK_SPACE: key = TK_SPACE; break;
  341. case VK_RETURN: key = TK_RETURN; break;
  342. case VK_ESCAPE: key = TK_ESCAPE; break;
  343. case VK_LEFT: key = TK_LEFT; break;
  344. case VK_UP: key = TK_UP; break;
  345. case VK_RIGHT: key = TK_RIGHT; break;
  346. case VK_DOWN: key = TK_DOWN; break;
  347. default: key = GL_FALSE; break;
  348. }
  349. if (key && pmtkwin->KeyDownFunc)
  350. {
  351. GLenum mask;
  352. mask = 0;
  353. if (GetKeyState(VK_CONTROL)) {
  354. mask |= TK_CONTROL;
  355. }
  356. if (GetKeyState(VK_SHIFT)) {
  357. mask |= TK_SHIFT;
  358. }
  359. if ( (*pmtkwin->KeyDownFunc)(key, mask) )
  360. {
  361. ForceRedraw( hWnd );
  362. }
  363. }
  364. return (0);
  365. case WM_CHAR:
  366. if (('0' <= wParam && wParam <= '9') ||
  367. ('a' <= wParam && wParam <= 'z') ||
  368. ('A' <= wParam && wParam <= 'Z')) {
  369. key = wParam;
  370. } else {
  371. key = GL_FALSE;
  372. }
  373. if (key && pmtkwin->KeyDownFunc) {
  374. GLenum mask;
  375. mask = 0;
  376. if (GetKeyState(VK_CONTROL)) {
  377. mask |= TK_CONTROL;
  378. }
  379. if (GetKeyState(VK_SHIFT)) {
  380. mask |= TK_SHIFT;
  381. }
  382. if ( (*pmtkwin->KeyDownFunc)(key, mask) )
  383. {
  384. ForceRedraw( hWnd );
  385. }
  386. }
  387. return (0);
  388. }
  389. return 0;
  390. }
  391. static void
  392. ForceRedraw( HWND hwnd )
  393. {
  394. MSG Message;
  395. #if 0
  396. if (!PeekMessage(&Message, hwnd, WM_PAINT, WM_PAINT, PM_NOREMOVE) )
  397. {
  398. InvalidateRect( hwnd, NULL, FALSE );
  399. }
  400. #else
  401. //mf: There is a problem with doing the redraw via WM_PAINT. WM_PAINT is sent
  402. // by the system when part of the window needs to be redrawn. For transparent
  403. // windows, we hook a grab background off of this, so if we use WM_PAINT for
  404. // our redraws, we'll just grab the previous gl image. Solutions are :
  405. // 1) Call redraw proc immediately here (possible timing problem)
  406. // 2) * Send redraw msg to queue
  407. // Possible side-effect : by not sending a WM_PAINT, the system is less
  408. // informed about what we're doing, but heck, we don't use PAINT for animations
  409. // anyways.
  410. if (!PeekMessage(&Message, hwnd, MTK_WM_REDRAW, MTK_WM_REDRAW, PM_NOREMOVE) )
  411. {
  412. PostMessage( hwnd, MTK_WM_REDRAW, 0, 0l );
  413. }
  414. #endif
  415. }
  416. /**************************************************************************\
  417. * UpdateDIBColorTable
  418. *
  419. * Wrapper for SSDIB_UpdateColorTable.
  420. *
  421. * This controls the hPal parameter for SSDIB_UpdateColorTable.
  422. *
  423. \**************************************************************************/
  424. void
  425. ssw_UpdateDIBColorTable( HDC hdcbm, HDC hdcwin )
  426. {
  427. SS_PAL *pssPal = gpssPal;
  428. if( !pssPal )
  429. return;
  430. #if 0
  431. HPALETTE hpal = pssPal->bTakeOver ? pssPal->hPal : NULL;
  432. #else
  433. HPALETTE hpal = pssPal->hPal;
  434. #endif
  435. SSDIB_UpdateColorTable( hdcbm, hdcwin, hpal );
  436. }
  437. /**************************************************************************\
  438. * RealizePalette
  439. *
  440. \**************************************************************************/
  441. static void
  442. ssw_RealizePalette( PMTKWIN pmtkwin, BOOL bBackground )
  443. {
  444. // assumed pssPal valid if get here
  445. SS_PAL *pssPal = gpssPal;
  446. if( !pmtkwin->hrc ) {
  447. // Can assume this window doesn't need to worry about palettes, but
  448. // if any of its children are subWindows, it will have to take care
  449. // of it *for* them.
  450. return; // no hrc and no subWindow children
  451. }
  452. pssPal->Realize( pmtkwin->hwnd, pmtkwin->hdc, bBackground );
  453. }
  454. /**************************************************************************\
  455. * ssw_DeletePalette
  456. *
  457. \**************************************************************************/
  458. static void
  459. ssw_DeletePalette( PMTKWIN pmtkwin )
  460. {
  461. SS_PAL *pssPal = gpssPal;
  462. //mf: !!! ? this din't seem to be used
  463. #if 0
  464. if( pssPal->bTakeOver ) {
  465. // We took over the system palette - make a note of this
  466. // for any special ss termination conditions.
  467. gpss->flags |= SS_PALETTE_TAKEOVER;
  468. }
  469. #endif
  470. pssPal->SetDC( pmtkwin->hdc );
  471. delete pssPal;
  472. gpssPal = NULL;
  473. }
  474. /**************************************************************************\
  475. * PaletteManage Procs
  476. \**************************************************************************/
  477. /* palette related msgs's:
  478. - WM_ACTIVATE:
  479. The WM_ACTIVATE message is sent when a window is being activated or
  480. deactivated. This message is sent first to the window procedure of
  481. the top-level window being deactivated; it is then sent to the
  482. window procedure of the top-level window being activated.
  483. - WM_QUERYNEWPALETTE:
  484. The WM_QUERYNEWPALETTE message informs a window that it is about
  485. to receive the keyboard focus, giving the window the opportunity
  486. to realize its logical palette when it receives the focus.
  487. If the window realizes its logical palette, it must return TRUE;
  488. otherwise, it must return FALSE.
  489. - WM_PALETTECHANGED:
  490. The WM_PALETTECHANGED message is sent to all top-level and overlapped
  491. windows after the window with the keyboard focus has realized its
  492. logical palette, thereby changing the system palette. This message
  493. enables a window that uses a color palette but does not have the
  494. keyboard focus to realize its logical palette and update its client
  495. area.
  496. This message must be sent to all top-level and overlapped windows,
  497. including the one that changed the system palette. If any child
  498. windows use a color palette, this message must be passed on to them
  499. as well.
  500. To avoid creating an infinite loop, a window that receives this
  501. message must not realize its palette, unless it determines that
  502. wParam does not contain its own window handle.
  503. - WM_SYSCOLORCHANGE:
  504. The WM_SYSCOLORCHANGE message is sent to all top-level windows when
  505. a change is made to a system color setting.
  506. - MTK_WM_PALETTE:
  507. Internal msg. Uses:
  508. - In fullscreen mode, we send this from Main wndproc to main
  509. window's children on WM_ACTIVATE.
  510. - When this is received in SS_ScreenSaverProc, if fullscreen,
  511. it does:
  512. UnrealizeObject( pssPal->hPal );
  513. RealizePalette( hdc );
  514. otherwise, it is passed to PaletteManageProc, where
  515. Realize is called (for 'floater' windows to realize
  516. their palettes).
  517. - It is also sent by DelayPaletteRealization() when it can't get
  518. the system palette.
  519. */
  520. /**************************************************************************\
  521. * MainPaletteManageProc
  522. *
  523. * Top-level palette management proc.
  524. * Returns immediately if no palette set - otherwise calls through
  525. * paletteManageProc function pointer
  526. *
  527. \**************************************************************************/
  528. LONG
  529. MainPaletteManageProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  530. {
  531. if( !gpssPal )
  532. // No palette management required
  533. return 0;
  534. // else call approppriate palette manage proc
  535. return (*gpssPal->paletteManageProc)(hwnd, message, wParam, lParam);
  536. }
  537. /**************************************************************************\
  538. * FullScreenPaletteManageProc
  539. *
  540. * Processes messages relating to palette management in full screen mode.
  541. *
  542. \**************************************************************************/
  543. LONG
  544. FullScreenPaletteManageProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  545. {
  546. SS_PAL *pssPal;
  547. MTKWIN *pmtkwin;
  548. switch (message)
  549. {
  550. case WM_ACTIVATE:
  551. #if SS_DEBUG
  552. if ( LOWORD(wParam) == WA_INACTIVE )
  553. SS_DBGMSG1( "FullScreen_PMProc: WM_ACTIVATE : inactive for 0x%x\n",
  554. hwnd );
  555. else
  556. SS_DBGMSG1( "FullScreen_PMProc: WM_ACTIVATE : active for 0x%x\n",
  557. hwnd );
  558. #endif
  559. // !! This msg is only sent to main top level window
  560. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  561. pssPal = gpssPal;
  562. if ( pssPal->bUseStatic ) {
  563. HDC hdc = pmtkwin->hdc; // hdc *always* valid for top-level pssw
  564. // Note: wParam = 0 when window going *inactive*
  565. SetSystemPaletteUse( hdc, wParam ? SYSPAL_NOSTATIC
  566. : pssPal->uiOldStaticUse);
  567. }
  568. // Send MTK_WM_PALETTE msg to main window
  569. SendMessage( hwnd, MTK_WM_PALETTE, wParam, 0);
  570. break;
  571. case MTK_WM_PALETTE:
  572. SS_DBGMSG1( "FullScreen_PMProc: MTK_WM_PALETTE for 0x%x\n", hwnd );
  573. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  574. HDC hdc;
  575. if( hdc = pmtkwin->hdc )
  576. {
  577. pssPal = gpssPal;
  578. //mf: this should call thru ssw_RealizePalette for bitmap case ? (for now
  579. // don't need to, since we take over palette...)
  580. // This resets the logical palette, causing remapping of
  581. // logical palette to system palette
  582. // mf: !!! ?? how come no dc with UnrealizeObject ? does that
  583. // mean its done once per app, not per child window ?
  584. // yeah, we should move this up...
  585. UnrealizeObject( pssPal->hPal );
  586. RealizePalette( hdc );
  587. }
  588. break;
  589. }
  590. return 0;
  591. }
  592. /**************************************************************************\
  593. * PaletteManageProc
  594. *
  595. * Processes messages relating to palette management for the general case.
  596. *
  597. * Note: this msg handling strategy is based loosely on the tk, so any changes
  598. * there should be reflected here
  599. \**************************************************************************/
  600. LONG
  601. PaletteManageProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  602. {
  603. // One global palette for all windows
  604. MTKWIN *pmtkwin;
  605. if( !gpssPal )
  606. return 0;
  607. switch (message)
  608. {
  609. case WM_ACTIVATE:
  610. SendMessage( hwnd, MTK_WM_PALETTE, bInBackground, 0);
  611. // Allow DefWindowProc() to finish the default processing (which
  612. // includes changing the keyboard focus).
  613. //mf: I added this - watch out for ss implications
  614. return DefWindowProc( hwnd, message, wParam, lParam );
  615. break;
  616. case WM_QUERYNEWPALETTE:
  617. #if 0
  618. SS_DBGMSG1( "Palette_Proc: WM_QUERYNEWPALETTE for 0x%x\n", hwnd );
  619. // We don't actually realize palette here (we do it at WM_ACTIVATE
  620. // time), but we need the system to think that we have so that a
  621. // WM_PALETTECHANGED message is generated.
  622. //mf: why can't we just realize here ? and who wants even more messages to
  623. // be generated !!! :)
  624. // This is the only msg preview mode gets wrt palettes !
  625. if( !ss_fPreviewMode() )
  626. return (1);
  627. // We are in preview mode - realize the palette
  628. SendMessage( hwnd, MTK_WM_PALETTE, bInBackground, 0);
  629. break;
  630. #else
  631. return (1);
  632. #endif
  633. case WM_PALETTECHANGED:
  634. SS_DBGMSG1( "Palette_Proc: WM_PALETTECHANGED for 0x%x\n", hwnd );
  635. // Respond to this message only if the window that changed the palette
  636. // is not this app's window.
  637. // We are not the foreground window, so realize palette in the
  638. // background. We cannot call Realize to do this because
  639. // we should not do any of the gbUseStaticColors processing while
  640. // in background.
  641. // Actually, we *can* be the fg window, so don't realize if
  642. // we're in foreground
  643. if( (hwnd != (HWND) wParam) && bInBackground )
  644. SendMessage( hwnd, MTK_WM_PALETTE, TRUE, 0);
  645. break;
  646. case WM_SYSCOLORCHANGE:
  647. // If the system colors have changed and we have a palette
  648. // for an RGB surface then we need to recompute the static
  649. // color mapping because they might have been changed in
  650. // the process of changing the system colors.
  651. SS_DBGMSG1( "Palette_Proc: WM_SYSCOLORCHANGE for 0x%x\n", hwnd );
  652. gpssPal->ReCreateRGBPalette();
  653. SendMessage( hwnd, MTK_WM_PALETTE, bInBackground, 0);
  654. break;
  655. case MTK_WM_PALETTE:
  656. SS_DBGMSG2( "Palette_Proc: MTK_WM_PALETTE for 0x%x, bg = %d\n",
  657. hwnd, wParam );
  658. // Realize palette for this window and its children
  659. // wParam = TRUE if realize as bg
  660. pmtkwin = sswTable.PsswFromHwnd( hwnd );
  661. ssw_RealizePalette( pmtkwin, wParam );
  662. break;
  663. }
  664. return 0;
  665. }
  666. /******************************Public*Routine******************************\
  667. * SSW_TABLE constructor
  668. *
  669. \**************************************************************************/
  670. SSW_TABLE::SSW_TABLE()
  671. {
  672. nEntries = 0;
  673. }
  674. /******************************Public*Routine******************************\
  675. * Register
  676. *
  677. * Register a HWND/PSSW pair.
  678. \**************************************************************************/
  679. void
  680. SSW_TABLE::Register( HWND hwnd, PMTKWIN pssw )
  681. {
  682. SSW_TABLE_ENTRY *pEntry;
  683. // Check if already in table
  684. if( PsswFromHwnd( hwnd ) )
  685. return;
  686. // put hwnd/pssw pair in the table
  687. pEntry = &sswTable[nEntries];
  688. pEntry->hwnd = hwnd;
  689. pEntry->pssw = pssw;
  690. nEntries++;
  691. }
  692. /******************************Public*Routine******************************\
  693. * PsswFromHwnd
  694. *
  695. * Return PSSW for the HWND
  696. \**************************************************************************/
  697. PMTKWIN
  698. SSW_TABLE::PsswFromHwnd( HWND hwnd )
  699. {
  700. int count = nEntries;
  701. SSW_TABLE_ENTRY *pEntry = sswTable;
  702. while( count-- ) {
  703. if( pEntry->hwnd == hwnd )
  704. return pEntry->pssw;
  705. pEntry++;
  706. }
  707. return NULL;
  708. }
  709. /******************************Public*Routine******************************\
  710. * Remove
  711. *
  712. * Remove HWND/PSSW entry from table
  713. \**************************************************************************/
  714. BOOL
  715. SSW_TABLE::Remove( HWND hwnd )
  716. {
  717. SSW_TABLE_ENTRY *pEntry = sswTable;
  718. // Locate the hwnd/pssw pair
  719. for( int count = 0 ; count < nEntries ; count++, pEntry++ ) {
  720. if( pEntry->hwnd == hwnd )
  721. break;
  722. }
  723. if( count == nEntries )
  724. // couldn't find it in the table
  725. return FALSE;
  726. // Remove entry / shuffle up other entries
  727. for( int i = count; i < nEntries-1; i ++ ) {
  728. sswTable[i] = sswTable[i+1];
  729. }
  730. nEntries--;
  731. return TRUE;
  732. }