1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/gtk/nsScreenGtk.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,156 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsScreenGtk.h" 1.10 + 1.11 +#include <gdk/gdk.h> 1.12 +#ifdef MOZ_X11 1.13 +#include <gdk/gdkx.h> 1.14 +#include <X11/Xatom.h> 1.15 +#endif 1.16 +#include <gtk/gtk.h> 1.17 + 1.18 +nsScreenGtk :: nsScreenGtk ( ) 1.19 + : mScreenNum(0), 1.20 + mRect(0, 0, 0, 0), 1.21 + mAvailRect(0, 0, 0, 0) 1.22 +{ 1.23 +} 1.24 + 1.25 + 1.26 +nsScreenGtk :: ~nsScreenGtk() 1.27 +{ 1.28 +} 1.29 + 1.30 + 1.31 +NS_IMETHODIMP 1.32 +nsScreenGtk :: GetRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight) 1.33 +{ 1.34 + *outLeft = mRect.x; 1.35 + *outTop = mRect.y; 1.36 + *outWidth = mRect.width; 1.37 + *outHeight = mRect.height; 1.38 + 1.39 + return NS_OK; 1.40 + 1.41 +} // GetRect 1.42 + 1.43 + 1.44 +NS_IMETHODIMP 1.45 +nsScreenGtk :: GetAvailRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight) 1.46 +{ 1.47 + *outLeft = mAvailRect.x; 1.48 + *outTop = mAvailRect.y; 1.49 + *outWidth = mAvailRect.width; 1.50 + *outHeight = mAvailRect.height; 1.51 + 1.52 + return NS_OK; 1.53 + 1.54 +} // GetAvailRect 1.55 + 1.56 + 1.57 +NS_IMETHODIMP 1.58 +nsScreenGtk :: GetPixelDepth(int32_t *aPixelDepth) 1.59 +{ 1.60 + GdkVisual * visual = gdk_screen_get_system_visual(gdk_screen_get_default()); 1.61 + *aPixelDepth = gdk_visual_get_depth(visual); 1.62 + 1.63 + return NS_OK; 1.64 + 1.65 +} // GetPixelDepth 1.66 + 1.67 + 1.68 +NS_IMETHODIMP 1.69 +nsScreenGtk :: GetColorDepth(int32_t *aColorDepth) 1.70 +{ 1.71 + return GetPixelDepth ( aColorDepth ); 1.72 + 1.73 +} // GetColorDepth 1.74 + 1.75 + 1.76 +void 1.77 +nsScreenGtk :: Init (GdkWindow *aRootWindow) 1.78 +{ 1.79 + // We listen for configure events on the root window to pick up 1.80 + // changes to this rect. We could listen for "size_changed" signals 1.81 + // on the default screen to do this, except that doesn't work with 1.82 + // versions of GDK predating the GdkScreen object. See bug 256646. 1.83 + mAvailRect = mRect = nsIntRect(0, 0, gdk_screen_width(), gdk_screen_height()); 1.84 + 1.85 +#ifdef MOZ_X11 1.86 + // We need to account for the taskbar, etc in the available rect. 1.87 + // See http://freedesktop.org/Standards/wm-spec/index.html#id2767771 1.88 + 1.89 + // XXX do we care about _NET_WM_STRUT_PARTIAL? That will 1.90 + // add much more complexity to the code here (our screen 1.91 + // could have a non-rectangular shape), but should 1.92 + // lead to greater accuracy. 1.93 + 1.94 + long *workareas; 1.95 + GdkAtom type_returned; 1.96 + int format_returned; 1.97 + int length_returned; 1.98 + 1.99 + GdkAtom cardinal_atom = gdk_x11_xatom_to_atom(XA_CARDINAL); 1.100 + 1.101 + gdk_error_trap_push(); 1.102 + 1.103 + // gdk_property_get uses (length + 3) / 4, hence G_MAXLONG - 3 here. 1.104 + if (!gdk_property_get(aRootWindow, 1.105 + gdk_atom_intern ("_NET_WORKAREA", FALSE), 1.106 + cardinal_atom, 1.107 + 0, G_MAXLONG - 3, FALSE, 1.108 + &type_returned, 1.109 + &format_returned, 1.110 + &length_returned, 1.111 + (guchar **) &workareas)) { 1.112 + // This window manager doesn't support the freedesktop standard. 1.113 + // Nothing we can do about it, so assume full screen size. 1.114 + return; 1.115 + } 1.116 + 1.117 + // Flush the X queue to catch errors now. 1.118 + gdk_flush(); 1.119 + 1.120 + if (!gdk_error_trap_pop() && 1.121 + type_returned == cardinal_atom && 1.122 + length_returned && (length_returned % 4) == 0 && 1.123 + format_returned == 32) { 1.124 + int num_items = length_returned / sizeof(long); 1.125 + 1.126 + for (int i = 0; i < num_items; i += 4) { 1.127 + nsIntRect workarea(workareas[i], workareas[i + 1], 1.128 + workareas[i + 2], workareas[i + 3]); 1.129 + if (!mRect.Contains(workarea)) { 1.130 + // Note that we hit this when processing screen size changes, 1.131 + // since we'll get the configure event before the toolbars have 1.132 + // been moved. We'll end up cleaning this up when we get the 1.133 + // change notification to the _NET_WORKAREA property. However, 1.134 + // we still want to listen to both, so we'll handle changes 1.135 + // properly for desktop environments that don't set the 1.136 + // _NET_WORKAREA property. 1.137 + NS_WARNING("Invalid bounds"); 1.138 + continue; 1.139 + } 1.140 + 1.141 + mAvailRect.IntersectRect(mAvailRect, workarea); 1.142 + } 1.143 + } 1.144 + g_free (workareas); 1.145 +#endif 1.146 +} 1.147 + 1.148 +#ifdef MOZ_X11 1.149 +void 1.150 +nsScreenGtk :: Init (XineramaScreenInfo *aScreenInfo) 1.151 +{ 1.152 + nsIntRect xineRect(aScreenInfo->x_org, aScreenInfo->y_org, 1.153 + aScreenInfo->width, aScreenInfo->height); 1.154 + 1.155 + mScreenNum = aScreenInfo->screen_number; 1.156 + 1.157 + mAvailRect = mRect = xineRect; 1.158 +} 1.159 +#endif