sbNativeWindowManager.cpp
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25  */
26 
33 #include "sbNativeWindowManager.h"
34 #include "../NativeWindowFromNode.h"
35 
36 #include <gdk/gdkx.h>
37 #include <gdk/gdk.h>
38 #include <gtk/gtkwindow.h>
39 
40 /* define this to use the X & Y from Mozilla DOM event */
41 #undef MOUSE_POSITION_FROM_EVENT
42 
44 
45 /* a helper function to return our toplevel GDK window given a Mozilla window. */
46 static nsresult
47 GetToplevelGdkWindow(nsISupports* aWindow, GdkWindow** aToplevelWindow) {
48  GdkWindow* window;
49 
50  /* we need somewhere to put the result */
51  if (!aToplevelWindow) {
52  return NS_ERROR_FAILURE;
53  }
54 
55  /* find the window that was passed in */
56  window = NativeWindowFromNode::get(aWindow);
57  if (!GDK_IS_WINDOW(window)) {
58  return NS_ERROR_FAILURE;
59  }
60 
61  /* no, actually we want the top-level window since we're doing a resize */
62  window = gdk_window_get_toplevel(window);
63  if (!GDK_IS_WINDOW(window)) {
64  return NS_ERROR_FAILURE;
65  }
66 
67  *aToplevelWindow = window;
68  return NS_OK;
69 }
70 
71 /* a helper function to return our toplevel Gtk+ window given a Mozilla window. */
72 static nsresult
73 GetToplevelGtkWindow(nsISupports* aWindow, GtkWindow** aToplevelWindow) {
74  GdkWindow* gdkwindow = NULL;
75  GtkWindow* gtkwindow = NULL;
76  gpointer user_data = NULL;
77  nsresult rv;
78 
79  // get the gdk window from the mozilla window
80  rv = GetToplevelGdkWindow(aWindow, &gdkwindow);
81  NS_ENSURE_SUCCESS(rv, rv);
82 
83  // get the gtk window from the gdk window
84  gdk_window_get_user_data(gdkwindow, &user_data);
85  if (!user_data) {
86  return NS_ERROR_FAILURE;
87  }
88 
89  // make sure it's really a gtk window
90  gtkwindow = GTK_WINDOW(user_data);
91 
92  // return it
93  *aToplevelWindow = gtkwindow;
94  return NS_OK;
95 }
96 
97 
98 NS_IMETHODIMP sbNativeWindowManager::BeginResizeDrag(nsISupports *aWindow, nsIDOMMouseEvent* aEvent, PRInt32 aDirection)
99 {
100  nsresult rv;
101  PRInt32 screenX;
102  PRInt32 screenY;
103  PRUint16 button;
104  PRUint32 server_time;
105  GdkWindow* window = NULL;
106  GdkWindowEdge window_edge;
107 
108  NS_ENSURE_ARG_POINTER(aWindow);
109  NS_ENSURE_ARG_POINTER(aEvent);
110 
111  /* find the window that was passed in */
112  rv = GetToplevelGdkWindow(aWindow, &window);
113  NS_ENSURE_SUCCESS(rv, rv);
114 
115  /* get the currently pressed mouse button from the event */
116  rv = aEvent->GetButton(&button);
117  NS_ENSURE_SUCCESS(rv, rv);
118  /* mozilla and gtk disagree about button numbering... */
119  button++;
120 
121  /* to work around an old, buggy metacity we need to move ourselves */
122  /* where are we? */
123  gdk_window_get_position(window, &screenX, &screenY);
124  /* let's move to there */
125  gdk_window_move(window, screenX, screenY);
126 
127 
128 #ifdef MOUSE_POSITION_FROM_EVENT
129  /* pull the mouse position out of the mozilla event */
130  rv = aEvent->GetScreenX(&screenX);
131  NS_ENSURE_SUCCESS(rv, rv);
132  rv = aEvent->GetScreenY(&screenY);
133  NS_ENSURE_SUCCESS(rv, rv);
134 #else
135  {
136  /* ask X where the mouse is */
137  GdkDisplay* display = NULL;
138  GdkScreen* screen = NULL;
139  GdkModifierType mask;
140  /* get the current (default) display */
141  display = gdk_display_get_default();
142  if (display == NULL) {
143  return NS_ERROR_FAILURE;
144  }
145  /* get the current pointer position */
146  gdk_display_get_pointer(display, &screen, &screenX, &screenY, &mask);
147  }
148 #endif
149 
150  /* convert interface directions to GDK_WINDOW_EDGE* */
151  switch(aDirection) {
153  window_edge = GDK_WINDOW_EDGE_NORTH_WEST;
154  break;
156  window_edge = GDK_WINDOW_EDGE_NORTH;
157  break;
159  window_edge = GDK_WINDOW_EDGE_NORTH_EAST;
160  break;
162  window_edge = GDK_WINDOW_EDGE_WEST;
163  break;
165  window_edge = GDK_WINDOW_EDGE_EAST;
166  break;
168  window_edge = GDK_WINDOW_EDGE_SOUTH_WEST;
169  break;
171  window_edge = GDK_WINDOW_EDGE_SOUTH;
172  break;
174  window_edge = GDK_WINDOW_EDGE_SOUTH_EAST;
175  break;
176  default:
177  return NS_ERROR_FAILURE;
178  }
179 
180  /* if I were an event, when would I happen? */
181  server_time = gdk_x11_get_server_time(window);
182 
183  /* tell the window manager to start the resize */
184  gdk_window_begin_resize_drag(window, window_edge, button,
185  screenX, screenY, server_time);
186 
187  return NS_OK;
188 }
189 
190 
191 NS_IMETHODIMP sbNativeWindowManager::GetSupportsResizeDrag(PRBool *aSupportsResizeDrag)
192 {
193  NS_ENSURE_ARG_POINTER(aSupportsResizeDrag);
194 
195  *aSupportsResizeDrag = PR_TRUE;
196 
197  return NS_OK;
198 }
199 
200 
201 NS_IMETHODIMP sbNativeWindowManager::SetMinimumWindowSize(nsISupports *aWindow, PRInt32 aMinimumWidth, PRInt32 aMinimumHeight)
202 {
203  nsresult rv;
204  GdkWindow* window = NULL;
205  GdkGeometry hints;
206 
207  NS_ENSURE_ARG_POINTER(aWindow);
208 
209  /* find the window that was passed in */
210  rv = GetToplevelGdkWindow(aWindow, &window);
211  NS_ENSURE_SUCCESS(rv, rv);
212 
213  /* set up the GdkGeometry with the info we have */
214  hints.min_width = aMinimumWidth;
215  hints.min_height = aMinimumHeight;
216  gdk_window_set_geometry_hints(window, &hints, GDK_HINT_MIN_SIZE);
217 
218  return NS_OK;
219 }
220 
221 
222 NS_IMETHODIMP sbNativeWindowManager::SetMaximumWindowSize(nsISupports *aWindow, PRInt32 aMaximumWidth, PRInt32 aMaximumHeight)
223 {
224  return NS_ERROR_NOT_IMPLEMENTED;
225 }
226 
227 
228 NS_IMETHODIMP sbNativeWindowManager::GetSupportsMinimumWindowSize(PRBool *aSupportsMinimumWindowSize)
229 {
230  NS_ENSURE_ARG_POINTER(aSupportsMinimumWindowSize);
231  *aSupportsMinimumWindowSize = PR_TRUE;
232  return NS_OK;
233 }
234 
235 
236 NS_IMETHODIMP sbNativeWindowManager::GetSupportsMaximumWindowSize(PRBool *aSupportsMaximumWindowSize)
237 {
238  NS_ENSURE_ARG_POINTER(aSupportsMaximumWindowSize);
239  *aSupportsMaximumWindowSize = PR_FALSE;
240  return NS_OK;
241 }
242 
243 
244 NS_IMETHODIMP sbNativeWindowManager::SetOnTop(nsISupports *aWindow, PRBool aOnTop)
245 {
246  nsresult rv;
247  GtkWindow* window = NULL;
248 
249  NS_ENSURE_ARG_POINTER(aWindow);
250 
251  /* if we're not mapped yet, we can't just set keep_above on our gdk window.
252  * if we do the gtk-window will override it when it maps. so we need to find
253  * the gtk window instead of the gdk window
254  */
255 
256  /* find the gtk window that was passed in */
257  rv = GetToplevelGtkWindow(aWindow, &window);
258  NS_ENSURE_SUCCESS(rv, rv);
259 
260  /* tell the window manager to put this window on top */
261  gtk_window_set_keep_above(window, aOnTop);
262 
263  return NS_OK;
264 }
265 
266 NS_IMETHODIMP sbNativeWindowManager::SetShadowing(nsISupports *aWindow, PRBool aShadowing)
267 {
268  return NS_ERROR_NOT_IMPLEMENTED;
269 }
270 
271 NS_IMETHODIMP sbNativeWindowManager::GetSupportsOnTop(PRBool *aSupportsOnTop)
272 {
273  NS_ENSURE_ARG_POINTER(aSupportsOnTop);
274 
275  *aSupportsOnTop = PR_TRUE;
276 
277  return NS_OK;
278 }
279 
280 NS_IMETHODIMP sbNativeWindowManager::GetSupportsShadowing(PRBool *aSupportsShadowing)
281 {
282  NS_ENSURE_ARG_POINTER(aSupportsShadowing);
283 
284  *aSupportsShadowing = PR_FALSE;
285 
286  return NS_OK;
287 }
return NS_OK
static nsresult GetToplevelGtkWindow(nsISupports *aWindow, GtkWindow **aToplevelWindow)
NS_IMPL_ISUPPORTS1(sbDeviceCapabilitiesUtils, sbIDeviceCapabilitiesUtils) sbDeviceCapabilitiesUtils
static nsresult GetToplevelGdkWindow(nsISupports *aWindow, GdkWindow **aToplevelWindow)
interface to the operating system's window manager This Interfaces to allows JavaScript to talk to th...
let window
static void * get(nsISupports *window)