Usermode/AxWin3 - Cleaned up focus code a little, added IPC focus call
[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
17 // === GLOBALS ===
18 //! Window in which the mouse button was originally pressed
19 tWindow *gpWM_DownStartWindow[MAX_BUTTONS];
20
21 // === CODE ===
22 tWindow *WM_int_GetWindowAtPos(int X, int Y)
23 {
24         tWindow *win, *next_win, *ret;
25         
26         next_win = gpWM_RootWindow;
27
28         while(next_win)
29         {
30                 ret = next_win;
31                 next_win = NULL;
32                 for(win = ret->FirstChild; win; win = win->NextSibling)
33                 {
34                         if( !(win->Flags & WINFLAG_SHOW) )      continue ;
35                         if( X < win->X || X >= win->X + win->W )        continue;
36                         if( Y < win->Y || Y >= win->Y + win->H )        continue;
37                         next_win = win; // Overwrite as we want the final rendered window
38                 }
39         }
40         
41         return ret;
42 }
43
44 void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY)
45 {
46         tWindow *win, *newWin;
47         struct sWndMsg_MouseMove        msg;
48         
49         win = WM_int_GetWindowAtPos(OldX, OldY);
50         msg.X = NewX - win->X;
51         msg.Y = NewY - win->Y;
52         msg.dX = NewX - OldX;
53         msg.dY = NewY - OldY;
54         WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg);
55         
56         // If the new coordinates are not in a new window
57         // NOTE: Should this handle crossing over a small window?
58         // - Nah, no need
59         newWin = WM_int_GetWindowAtPos(NewX, NewY);
60         if(win == newWin)       return;
61
62         // TODO: Send mouseup to match mousedown if the cursor moves out of a window?
63
64         win = newWin;
65         msg.X = NewX - win->X;
66         msg.Y = NewY - win->Y;
67         msg.dX = NewX - OldX;
68         msg.dY = NewY - OldY;
69         WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg);
70 }
71
72 inline void WM_Input_int_SendBtnMsg(tWindow *Win, int X, int Y, int Index, int Pressed)
73 {
74         struct sWndMsg_MouseButton      msg;    
75
76         msg.X = X - Win->X;
77         msg.Y = Y - Win->Y;
78         msg.Button = Index;
79         msg.bPressed = !!Pressed;
80         
81         WM_SendMessage(NULL, Win, WNDMSG_MOUSEBTN, sizeof(msg), &msg);
82 }
83
84 void WM_Input_MouseButton(int X, int Y, int ButtonIndex, int Pressed)
85 {
86         tWindow *win;
87
88         win = WM_int_GetWindowAtPos(X, Y);
89
90         // Handle press of primary button to change focus
91         if( ButtonIndex == 0 && Pressed == 1 )
92         {
93                 _SysDebug("Gave focus to %p", win);
94                 WM_FocusWindow(win);
95                 WM_RaiseWindow(win);
96         }
97
98         // Make sure that even if the mouse has moved out of the original window,
99         // mouse release messages reach the window.
100         if( !Pressed && ButtonIndex < MAX_BUTTONS && gpWM_DownStartWindow[ButtonIndex] != win )
101         {
102                 WM_Input_int_SendBtnMsg(gpWM_DownStartWindow[ButtonIndex], X, Y, ButtonIndex, 0);
103         }
104         if( Pressed && ButtonIndex < MAX_BUTTONS )
105         {
106                 gpWM_DownStartWindow[ButtonIndex] = win;
107         }
108
109         // Send Press/Release message
110         WM_Input_int_SendBtnMsg(win, X, Y, ButtonIndex, Pressed);
111 }
112

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