Back to index

lightning-sunbird  0.9+nobinonly
nsScreenGtk.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Christopher A. Aillon <caillon@redhat.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsScreenGtk.h"
00040 
00041 #include <gdk/gdk.h>
00042 #include <gdk/gdkx.h>
00043 #include <gtk/gtk.h>
00044 #include <X11/Xatom.h>
00045 
00046 nsScreenGtk :: nsScreenGtk (  )
00047   : mScreenNum(0),
00048     mRect(0, 0, 0, 0),
00049     mAvailRect(0, 0, 0, 0)
00050 {
00051 }
00052 
00053 
00054 nsScreenGtk :: ~nsScreenGtk()
00055 {
00056 }
00057 
00058 
00059 // addref, release, QI
00060 NS_IMPL_ISUPPORTS1(nsScreenGtk, nsIScreen)
00061 
00062 
00063 NS_IMETHODIMP
00064 nsScreenGtk :: GetRect(PRInt32 *outLeft, PRInt32 *outTop, PRInt32 *outWidth, PRInt32 *outHeight)
00065 {
00066   *outLeft = mRect.x;
00067   *outTop = mRect.y;
00068   *outWidth = mRect.width;
00069   *outHeight = mRect.height;
00070 
00071   return NS_OK;
00072   
00073 } // GetRect
00074 
00075 
00076 NS_IMETHODIMP
00077 nsScreenGtk :: GetAvailRect(PRInt32 *outLeft, PRInt32 *outTop, PRInt32 *outWidth, PRInt32 *outHeight)
00078 {
00079   *outLeft = mAvailRect.x;
00080   *outTop = mAvailRect.y;
00081   *outWidth = mAvailRect.width;
00082   *outHeight = mAvailRect.height;
00083 
00084   return NS_OK;
00085   
00086 } // GetAvailRect
00087 
00088 
00089 NS_IMETHODIMP 
00090 nsScreenGtk :: GetPixelDepth(PRInt32 *aPixelDepth)
00091 {
00092   GdkVisual * rgb_visual = gdk_rgb_get_visual();
00093   *aPixelDepth = rgb_visual->depth;
00094 
00095   return NS_OK;
00096 
00097 } // GetPixelDepth
00098 
00099 
00100 NS_IMETHODIMP 
00101 nsScreenGtk :: GetColorDepth(PRInt32 *aColorDepth)
00102 {
00103   return GetPixelDepth ( aColorDepth );
00104 
00105 } // GetColorDepth
00106 
00107 
00108 void
00109 nsScreenGtk :: Init ()
00110 {
00111   mAvailRect = mRect = nsRect(0, 0, gdk_screen_width(), gdk_screen_height());
00112 
00113   // We need to account for the taskbar, etc in the available rect.
00114   // See http://freedesktop.org/Standards/wm-spec/index.html#id2767771
00115 
00116   // XXX It doesn't change that often, but we should probably
00117   // listen for changes to _NET_WORKAREA.
00118   // XXX do we care about _NET_WM_STRUT_PARTIAL?  That will
00119   // add much more complexity to the code here (our screen
00120   // could have a non-rectangular shape), but should
00121   // lead to greater accuracy.
00122 
00123 #if GTK_CHECK_VERSION(2,2,0)
00124   GdkWindow *root_window = gdk_get_default_root_window();
00125 #else
00126   GdkWindow *root_window = GDK_ROOT_PARENT();
00127 #endif // GTK_CHECK_VERSION(2,2,0)
00128 
00129   long *workareas;
00130   GdkAtom type_returned;
00131   int format_returned;
00132   int length_returned;
00133 
00134 #if GTK_CHECK_VERSION(2,0,0)
00135   GdkAtom cardinal_atom = gdk_x11_xatom_to_atom(XA_CARDINAL);
00136 #else
00137   GdkAtom cardinal_atom = (GdkAtom) XA_CARDINAL;
00138 #endif
00139 
00140   gdk_error_trap_push();
00141 
00142   // gdk_property_get uses (length + 3) / 4, hence G_MAXLONG - 3 here.
00143   if (!gdk_property_get(root_window,
00144                         gdk_atom_intern ("_NET_WORKAREA", FALSE),
00145                         cardinal_atom,
00146                         0, G_MAXLONG - 3, FALSE,
00147                         &type_returned,
00148                         &format_returned,
00149                         &length_returned,
00150                         (guchar **) &workareas)) {
00151     // This window manager doesn't support the freedesktop standard.
00152     // Nothing we can do about it, so assume full screen size.
00153     return;
00154   }
00155 
00156   // Flush the X queue to catch errors now.
00157   gdk_flush();
00158 
00159   if (!gdk_error_trap_pop() &&
00160       type_returned == cardinal_atom &&
00161       length_returned && (length_returned % 4) == 0 &&
00162       format_returned == 32) {
00163     int num_items = length_returned / sizeof(long);
00164 
00165     for (int i = 0; i < num_items; i += 4) {
00166       nsRect workarea(workareas[i],     workareas[i + 1],
00167                       workareas[i + 2], workareas[i + 3]);
00168       if (!mRect.Contains(workarea)) {
00169         NS_WARNING("Invalid bounds");
00170         continue;
00171       }
00172 
00173       mAvailRect.IntersectRect(mAvailRect, workarea);
00174     }
00175   }
00176   g_free (workareas);
00177 }
00178 
00179 #ifdef MOZ_ENABLE_XINERAMA
00180 void
00181 nsScreenGtk :: Init (XineramaScreenInfo *aScreenInfo)
00182 {
00183   nsRect xineRect(aScreenInfo->x_org, aScreenInfo->y_org,
00184                   aScreenInfo->width, aScreenInfo->height);
00185 
00186   mScreenNum = aScreenInfo->screen_number;
00187 
00188   mAvailRect = mRect = xineRect;
00189 }
00190 #endif // MOZ_ENABLE_XINERAMA