Home | History | Annotate | Download | only in gfx
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef UI_GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_
      6 #define UI_GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_
      7 
      8 #include <map>
      9 
     10 #include "base/synchronization/lock.h"
     11 #include "ui/base/ui_export.h"
     12 #include "ui/gfx/native_widget_types.h"
     13 
     14 template <typename T> struct DefaultSingletonTraits;
     15 
     16 typedef unsigned long XID;
     17 struct _GtkPreserveWindow;
     18 
     19 // NativeViewIds are the opaque values which the renderer holds as a reference
     20 // to a window.
     21 //
     22 // We could make NativeViewIds be the X id of the window. However, at the
     23 // time when we need to tell the renderer about its NativeViewId, an XID isn't
     24 // availible and it goes very much against the grain of the code to make it so.
     25 // Also, we worry that GTK might choose to change the underlying X window id
     26 // when, say, the widget is hidden or repacked. Finally, if we used XIDs then a
     27 // compromised renderer could start asking questions about any X windows on the
     28 // system.
     29 //
     30 // Thus, we have this object. It produces random NativeViewIds from GtkWidget
     31 // pointers and observes the various signals from the widget for when an X
     32 // window is created, destroyed etc. Thus it provides a thread safe mapping
     33 // from NativeViewIds to the current XID for that widget.
     34 class UI_EXPORT GtkNativeViewManager {
     35  public:
     36   // Returns the singleton instance.
     37   static GtkNativeViewManager* GetInstance();
     38 
     39   // Must be called from the UI thread:
     40   //
     41   // Return a NativeViewId for the given widget and attach to the various
     42   // signals emitted by that widget. The NativeViewId is pseudo-randomly
     43   // allocated so that a compromised renderer trying to guess values will fail
     44   // with high probability. The NativeViewId will not be reused for the
     45   // lifetime of the GtkWidget.
     46   gfx::NativeViewId GetIdForWidget(gfx::NativeView widget);
     47 
     48   // May be called from any thread:
     49   //
     50   // xid: (output) the resulting X window ID, or 0
     51   // id: a value previously returned from GetIdForWidget
     52   // returns: true if |id| is a valid id, false otherwise.
     53   //
     54   // If the widget referenced by |id| does not current have an X window id,
     55   // |*xid| is set to 0.
     56   bool GetXIDForId(XID* xid, gfx::NativeViewId id);
     57 
     58   // May be called from the UI thread:
     59   //
     60   // Same as GetXIDForId except it returns the NativeView (GtkWidget*).
     61   bool GetNativeViewForId(gfx::NativeView* xid, gfx::NativeViewId id);
     62 
     63   // Must be called from the UI thread because we may need the associated
     64   // widget to create a window.
     65   //
     66   // Keeping the XID permanent requires a bit of overhead, so it must
     67   // be explicitly requested.
     68   //
     69   // xid: (output) the resulting X window
     70   // id: a value previously returned from GetIdForWidget
     71   // returns: true if |id| is a valid id, false otherwise.
     72   bool GetPermanentXIDForId(XID* xid, gfx::NativeViewId id);
     73 
     74   // Can be called from any thread.
     75   // Will return false if the given XID isn't permanent or has already been
     76   // released.
     77   bool AddRefPermanentXID(XID xid);
     78 
     79   // Must be called from the UI thread because we may need to access a
     80   // GtkWidget or destroy a GdkWindow.
     81   //
     82   // If the widget associated with the XID is still alive, allow the widget
     83   // to destroy the associated XID when it wants. Otherwise, destroy the
     84   // GdkWindow associated with the XID.
     85   void ReleasePermanentXID(XID xid);
     86 
     87   // These are actually private functions, but need to be called from statics.
     88   void OnRealize(gfx::NativeView widget);
     89   void OnUnrealize(gfx::NativeView widget);
     90   void OnDestroy(gfx::NativeView widget);
     91 
     92  private:
     93   // This object is a singleton:
     94   GtkNativeViewManager();
     95   ~GtkNativeViewManager();
     96   friend struct DefaultSingletonTraits<GtkNativeViewManager>;
     97 
     98   struct NativeViewInfo {
     99     NativeViewInfo() : widget(NULL), x_window_id(0) {
    100     }
    101     gfx::NativeView widget;
    102     XID x_window_id;
    103   };
    104 
    105   gfx::NativeViewId GetWidgetId(gfx::NativeView id);
    106 
    107   // protects native_view_to_id_ and id_to_info_
    108   base::Lock lock_;
    109 
    110   // If asked for an id for the same widget twice, we want to return the same
    111   // id. So this records the current mapping.
    112   std::map<gfx::NativeView, gfx::NativeViewId> native_view_to_id_;
    113   std::map<gfx::NativeViewId, NativeViewInfo> id_to_info_;
    114 
    115   struct PermanentXIDInfo {
    116     PermanentXIDInfo() : widget(NULL), ref_count(0) {
    117     }
    118     _GtkPreserveWindow* widget;
    119     int ref_count;
    120   };
    121 
    122   // Used to maintain the reference count for permanent XIDs
    123   // (referenced by GetPermanentXIDForId and dereferenced by
    124   // ReleasePermanentXID). Only those XIDs with a positive reference count
    125   // will be in the table.
    126   //
    127   // In general, several GTK widgets may share the same X window. We assume
    128   // that is not true of the widgets stored in this registry.
    129   //
    130   // An XID will map to NULL, if there is an outstanding reference but the
    131   // widget was destroyed. In this case, the destruction of the X window
    132   // is deferred to the dropping of all references.
    133   std::map<XID, PermanentXIDInfo> perm_xid_to_info_;
    134 
    135   DISALLOW_COPY_AND_ASSIGN(GtkNativeViewManager);
    136 };
    137 
    138 #endif  // UI_GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_
    139