Fixing bugs exposed by scan-build
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / wm_input.c
1 /*
2  * Acess2 Window Manager v3
3  * - By John Hodge (thePowersGang)
4  *
5  * wm.c
6  * - Window manager core
7  */
8 #include <common.h>
9 #include <wm_internals.h>
10 #include <wm_messages.h>
11
12 #define MAX_BUTTONS     3
13
14 // === IMPORTS ===
15 extern tWindow  *gpWM_RootWindow;
16 extern tWindow  *gpWM_FocusedWindow;
17
18 // === GLOBALS ===
19 //! Window in which the mouse button was originally pressed
20 tWindow *gpWM_DownStartWindow[MAX_BUTTONS];
21
22 // === CODE ===
23 tWindow *WM_int_GetWindowAtPos(int X, int Y)
24 {
25         tWindow *win, *next_win, *ret = NULL;
26         
27         next_win = gpWM_RootWindow;
28
29         while(next_win)
30         {
31                 ret = next_win;
32                 next_win = NULL;
33                 for(win = ret->FirstChild; win; win = win->NextSibling)
34                 {
35                         if( !(win->Flags & WINFLAG_SHOW) )      continue ;
36                         if( X < win->X || X >= win->X + win->W )        continue;
37                         if( Y < win->Y || Y >= win->Y + win->H )        continue;
38                         next_win = win; // Overwrite as we want the final rendered window
39                 }
40         }
41         
42         return ret;
43 }
44
45 void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY)
46 {
47         tWindow *win, *newWin;
48         struct sWndMsg_MouseMove        msg;
49         
50         win = WM_int_GetWindowAtPos(OldX, OldY);
51         msg.X = NewX - win->X - win->BorderL;
52         msg.Y = NewY - win->Y - win->BorderT;
53         msg.dX = NewX - OldX;
54         msg.dY = NewY - OldY;
55         WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg);
56         
57         // If the new coordinates are not in a new window
58         // NOTE: Should this handle crossing over a small window?
59         // - Nah, no need
60         newWin = WM_int_GetWindowAtPos(NewX, NewY);
61         if(win == newWin)       return;
62
63         // TODO: Send mouseup to match mousedown if the cursor moves out of a window?
64
65         win = newWin;
66         msg.X = NewX - win->X - win->BorderL;
67         msg.Y = NewY - win->Y - win->BorderT;
68         msg.dX = NewX - OldX;
69         msg.dY = NewY - OldY;
70         WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg);
71 }
72
73 inline void WM_Input_int_SendBtnMsg(tWindow *Win, int X, int Y, int Index, int Pressed)
74 {
75         struct sWndMsg_MouseButton      msg;    
76
77         msg.X = X - Win->X - Win->BorderL;
78         msg.Y = Y - Win->Y - Win->BorderT;
79         msg.Button = Index;
80         msg.bPressed = !!Pressed;
81         
82         WM_SendMessage(NULL, Win, WNDMSG_MOUSEBTN, sizeof(msg), &msg);
83 }
84
85 void WM_Input_MouseButton(int X, int Y, int ButtonIndex, int Pressed)
86 {
87         tWindow *win;
88
89         win = WM_int_GetWindowAtPos(X, Y);
90
91         // Handle press of primary button to change focus
92         if( ButtonIndex == 0 && Pressed == 1 )
93         {
94 //              _SysDebug("Gave focus to %p", win);
95                 WM_FocusWindow(win);
96                 WM_RaiseWindow(win);
97         }
98
99         // Make sure that even if the mouse has moved out of the original window,
100         // mouse release messages reach the window.
101         if( !Pressed && ButtonIndex < MAX_BUTTONS && gpWM_DownStartWindow[ButtonIndex] != win )
102         {
103                 WM_Input_int_SendBtnMsg(gpWM_DownStartWindow[ButtonIndex], X, Y, ButtonIndex, 0);
104         }
105         if( Pressed && ButtonIndex < MAX_BUTTONS )
106         {
107                 gpWM_DownStartWindow[ButtonIndex] = win;
108         }
109
110         // Send Press/Release message
111         WM_Input_int_SendBtnMsg(win, X, Y, ButtonIndex, Pressed);
112 }
113
114 void WM_Input_KeyDown(uint32_t Character, uint32_t Scancode)
115 {
116         struct sWndMsg_KeyAction        msg;
117         msg.KeySym = Scancode;
118         msg.UCS32 = Character;
119         WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYDOWN, sizeof(msg), &msg);
120 }
121
122 void WM_Input_KeyFire(uint32_t Character, uint32_t Scancode)
123 {
124         struct sWndMsg_KeyAction        msg;
125
126         // TODO: Properly translate into KeySyms and Unicode
127
128         msg.KeySym = Scancode;
129         msg.UCS32 = Character;
130         WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYFIRE, sizeof(msg), &msg);
131 }
132
133 void WM_Input_KeyUp(uint32_t Character, uint32_t Scancode)
134 {
135         struct sWndMsg_KeyAction        msg;
136         msg.KeySym = Scancode;
137         msg.UCS32 = Character;
138         WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYUP, sizeof(msg), &msg);
139 }
140

UCC git Repository :: git.ucc.asn.au