1 /*
2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Mouse keys notification icon handler
5 * COPYRIGHT: Copyright 2022 Mark Jansen <mark.jansen@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 static MOUSEKEYS g_Mk;
11 static UINT g_MkState;
12 static HICON g_MkStateIcon;
13
14 HRESULT STDMETHODCALLTYPE
MouseKeys_Init(_In_ CSysTray * pSysTray)15 MouseKeys_Init(_In_ CSysTray *pSysTray)
16 {
17 TRACE("MouseKeys_Init!\n");
18
19 return MouseKeys_Update(pSysTray);
20 }
21
22 HRESULT STDMETHODCALLTYPE
MouseKeys_Shutdown(_In_ CSysTray * pSysTray)23 MouseKeys_Shutdown(_In_ CSysTray *pSysTray)
24 {
25 TRACE("MouseKeys_Shutdown!\n");
26
27 if (g_MkStateIcon)
28 {
29 DestroyIcon(g_MkStateIcon);
30 g_MkStateIcon = NULL;
31 }
32
33 if (g_MkState)
34 {
35 g_MkState = 0;
36 pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_MOUSE, g_MkStateIcon, L"MouseKeys");
37 }
38
39 return S_OK;
40 }
41
42 HRESULT STDMETHODCALLTYPE
MouseKeys_Update(_In_ CSysTray * pSysTray)43 MouseKeys_Update(_In_ CSysTray *pSysTray)
44 {
45 TRACE("MouseKeys_Update!\n");
46
47 g_Mk.cbSize = sizeof(g_Mk);
48 SystemParametersInfoW(SPI_GETMOUSEKEYS, sizeof(g_Mk), &g_Mk, 0);
49
50 UINT state = 0;
51 if ((g_Mk.dwFlags & (MKF_INDICATOR | MKF_MOUSEKEYSON)) == (MKF_INDICATOR | MKF_MOUSEKEYSON))
52 {
53 if (g_Mk.dwFlags & MKF_MOUSEMODE)
54 {
55 switch (g_Mk.dwFlags & (MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONDOWN | MKF_RIGHTBUTTONSEL))
56 {
57 case 0:
58 default:
59 state = IDI_MOUSE_NOBTN;
60 break;
61 case MKF_LEFTBUTTONSEL:
62 state = IDI_MOUSE_L_ACTIVE;
63 break;
64 case MKF_LEFTBUTTONDOWN:
65 case MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL:
66 state = IDI_MOUSE_L_DOWN;
67 break;
68 case MKF_RIGHTBUTTONSEL:
69 state = IDI_MOUSE_R_ACTIVE;
70 break;
71 case MKF_RIGHTBUTTONDOWN:
72 case MKF_RIGHTBUTTONDOWN | MKF_RIGHTBUTTONSEL:
73 state = IDI_MOUSE_R_DOWN;
74 break;
75 case MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONSEL:
76 state = IDI_MOUSE_LR_ACTIVE;
77 break;
78 case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN:
79 case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL:
80 case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONSEL:
81 case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN | MKF_RIGHTBUTTONSEL:
82 state = IDI_MOUSE_LR_DOWN;
83 break;
84 case MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONDOWN:
85 case MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONDOWN | MKF_RIGHTBUTTONSEL:
86 state = IDI_MOUSE_L_ACTIVE_R_DOWN;
87 break;
88 case MKF_LEFTBUTTONDOWN | MKF_RIGHTBUTTONSEL:
89 case MKF_LEFTBUTTONDOWN | MKF_RIGHTBUTTONSEL | MKF_LEFTBUTTONSEL:
90 state = IDI_MOUSE_R_ACTIVE_L_DOWN;
91 break;
92 }
93 }
94 else
95 {
96 state = IDI_MOUSE_DISABLED;
97 }
98 }
99
100 UINT uId = NIM_MODIFY;
101 if (state != g_MkState)
102 {
103 if (g_MkStateIcon)
104 {
105 DestroyIcon(g_MkStateIcon);
106 g_MkStateIcon = NULL;
107 }
108
109 if (g_MkState == 0)
110 uId = NIM_ADD;
111
112 g_MkState = state;
113 if (g_MkState)
114 {
115 g_MkStateIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(g_MkState));
116 }
117 }
118
119 if (g_MkState == 0)
120 {
121 uId = NIM_DELETE;
122 }
123
124 return pSysTray->NotifyIcon(uId, ID_ICON_MOUSE, g_MkStateIcon, L"MouseKeys");
125 }
126