TODO
[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->X || X >= win->X + win->W )        continue;
38                         if( Y < win->Y || Y >= win->Y + win->H )        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->X - win->BorderL;
53         msg.Y = NewY - win->Y - 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->X - win->BorderL;
68         msg.Y = NewY - win->Y - 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->X - Win->BorderL;
79         msg.Y = Y - Win->Y - 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                 WM_RaiseWindow(win);
98         }
99
100         // Make sure that even if the mouse has moved out of the original window,
101         // mouse release messages reach the window.
102         if( !Pressed && ButtonIndex < MAX_BUTTONS && gpWM_DownStartWindow[ButtonIndex] != win )
103         {
104                 WM_Input_int_SendBtnMsg(gpWM_DownStartWindow[ButtonIndex], X, Y, ButtonIndex, 0);
105         }
106         if( Pressed && ButtonIndex < MAX_BUTTONS )
107         {
108                 gpWM_DownStartWindow[ButtonIndex] = win;
109         }
110
111         // Send Press/Release message
112         WM_Input_int_SendBtnMsg(win, X, Y, ButtonIndex, Pressed);
113 }
114
115 void WM_Input_KeyDown(uint32_t Character, uint32_t Scancode)
116 {
117         struct sWndMsg_KeyAction        msg;
118
119         WM_Hotkey_KeyDown(Scancode);
120
121         msg.KeySym = Scancode;
122         msg.UCS32 = Character;
123         WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYDOWN, sizeof(msg), &msg);
124 }
125
126 void WM_Input_KeyFire(uint32_t Character, uint32_t Scancode)
127 {
128         struct sWndMsg_KeyAction        msg;
129
130         // TODO: Properly translate into KeySyms and Unicode
131
132         msg.KeySym = Scancode;
133         msg.UCS32 = Character;
134         WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYFIRE, sizeof(msg), &msg);
135 }
136
137 void WM_Input_KeyUp(uint32_t Character, uint32_t Scancode)
138 {
139         struct sWndMsg_KeyAction        msg;
140
141         WM_Hotkey_KeyUp(Scancode);
142
143         msg.KeySym = Scancode;
144         msg.UCS32 = Character;
145         WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYUP, sizeof(msg), &msg);
146 }
147

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