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

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