LCOV - code coverage report
Current view: top level - widget/gtk - mozcontainer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 56 143 39.2 %
Date: 2017-07-14 16:53:18 Functions: 8 15 53.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* vim:expandtab:shiftwidth=4:tabstop=4:
       3             :  */
       4             : /* This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       7             : 
       8             : #include "mozcontainer.h"
       9             : #include <gtk/gtk.h>
      10             : #include <stdio.h>
      11             : 
      12             : #ifdef ACCESSIBILITY
      13             : #include <atk/atk.h>
      14             : #include "maiRedundantObjectFactory.h"
      15             : #endif 
      16             : 
      17             : /* init methods */
      18             : static void moz_container_class_init          (MozContainerClass *klass);
      19             : static void moz_container_init                (MozContainer      *container);
      20             : 
      21             : /* widget class methods */
      22             : static void moz_container_map                 (GtkWidget         *widget);
      23             : static void moz_container_unmap               (GtkWidget         *widget);
      24             : static void moz_container_realize             (GtkWidget         *widget);
      25             : static void moz_container_size_allocate       (GtkWidget         *widget,
      26             :                                                GtkAllocation     *allocation);
      27             : 
      28             : /* container class methods */
      29             : static void moz_container_remove      (GtkContainer      *container,
      30             :                                        GtkWidget         *child_widget);
      31             : static void moz_container_forall      (GtkContainer      *container,
      32             :                                        gboolean           include_internals,
      33             :                                        GtkCallback        callback,
      34             :                                        gpointer           callback_data);
      35             : static void moz_container_add         (GtkContainer      *container,
      36             :                                         GtkWidget        *widget);
      37             : 
      38             : typedef struct _MozContainerChild MozContainerChild;
      39             : 
      40             : struct _MozContainerChild {
      41             :     GtkWidget *widget;
      42             :     gint x;
      43             :     gint y;
      44             : };
      45             : 
      46             : static void moz_container_allocate_child (MozContainer      *container,
      47             :                                           MozContainerChild *child);
      48             : static MozContainerChild *
      49             : moz_container_get_child (MozContainer *container, GtkWidget *child);
      50             : 
      51             : /* public methods */
      52             : 
      53             : GType
      54          24 : moz_container_get_type(void)
      55             : {
      56             :     static GType moz_container_type = 0;
      57             : 
      58          24 :     if (!moz_container_type) {
      59             :         static GTypeInfo moz_container_info = {
      60             :             sizeof(MozContainerClass), /* class_size */
      61             :             NULL, /* base_init */
      62             :             NULL, /* base_finalize */
      63             :             (GClassInitFunc) moz_container_class_init, /* class_init */
      64             :             NULL, /* class_destroy */
      65             :             NULL, /* class_data */
      66             :             sizeof(MozContainer), /* instance_size */
      67             :             0, /* n_preallocs */
      68             :             (GInstanceInitFunc) moz_container_init, /* instance_init */
      69             :             NULL, /* value_table */
      70             :         };
      71             : 
      72           1 :         moz_container_type = g_type_register_static (GTK_TYPE_CONTAINER,
      73             :                                                      "MozContainer",
      74             :                                                      &moz_container_info,
      75             :                                                      static_cast<GTypeFlags>(0));
      76             : #ifdef ACCESSIBILITY
      77             :         /* Set a factory to return accessible object with ROLE_REDUNDANT for
      78             :          * MozContainer, so that gail won't send focus notification for it */
      79           2 :         atk_registry_set_factory_type(atk_get_default_registry(),
      80             :                                       moz_container_type,
      81           2 :                                       mai_redundant_object_factory_get_type());
      82             : #endif
      83             :     }
      84             : 
      85          24 :     return moz_container_type;
      86             : }
      87             : 
      88             : GtkWidget *
      89           2 : moz_container_new (void)
      90             : {
      91             :     MozContainer *container;
      92             : 
      93           2 :     container = static_cast<MozContainer*>(g_object_new (MOZ_CONTAINER_TYPE, nullptr));
      94             : 
      95           2 :     return GTK_WIDGET(container);
      96             : }
      97             : 
      98             : void
      99           0 : moz_container_put (MozContainer *container, GtkWidget *child_widget,
     100             :                    gint x, gint y)
     101             : {
     102             :     MozContainerChild *child;
     103             : 
     104           0 :     child = g_new (MozContainerChild, 1);
     105             : 
     106           0 :     child->widget = child_widget;
     107           0 :     child->x = x;
     108           0 :     child->y = y;
     109             : 
     110             :     /*  printf("moz_container_put %p %p %d %d\n", (void *)container,
     111             :         (void *)child_widget, x, y); */
     112             : 
     113           0 :     container->children = g_list_append (container->children, child);
     114             : 
     115             :     /* we assume that the caller of this function will have already set
     116             :        the parent GdkWindow because we can have many anonymous children. */
     117           0 :     gtk_widget_set_parent(child_widget, GTK_WIDGET(container));
     118           0 : }
     119             : 
     120             : void
     121           0 : moz_container_move (MozContainer *container, GtkWidget *child_widget,
     122             :                     gint x, gint y, gint width, gint height)
     123             : {
     124             :     MozContainerChild *child;
     125             :     GtkAllocation new_allocation;
     126             : 
     127           0 :     child = moz_container_get_child (container, child_widget);
     128             : 
     129           0 :     child->x = x;
     130           0 :     child->y = y;
     131             : 
     132           0 :     new_allocation.x = x;
     133           0 :     new_allocation.y = y;
     134           0 :     new_allocation.width = width;
     135           0 :     new_allocation.height = height;
     136             : 
     137             :     /* printf("moz_container_move %p %p will allocate to %d %d %d %d\n",
     138             :        (void *)container, (void *)child_widget,
     139             :        new_allocation.x, new_allocation.y,
     140             :        new_allocation.width, new_allocation.height); */
     141             : 
     142           0 :     gtk_widget_size_allocate(child_widget, &new_allocation);
     143           0 : }
     144             : 
     145             : /* static methods */
     146             : 
     147             : void
     148           1 : moz_container_class_init (MozContainerClass *klass)
     149             : {
     150             :     /*GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     151             :       GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); */
     152           1 :     GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
     153           1 :     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
     154             : 
     155           1 :     widget_class->map = moz_container_map;
     156           1 :     widget_class->unmap = moz_container_unmap;
     157           1 :     widget_class->realize = moz_container_realize;
     158           1 :     widget_class->size_allocate = moz_container_size_allocate;
     159             : 
     160           1 :     container_class->remove = moz_container_remove;
     161           1 :     container_class->forall = moz_container_forall;
     162           1 :     container_class->add = moz_container_add;
     163           1 : }
     164             : 
     165             : void
     166           2 : moz_container_init (MozContainer *container)
     167             : {
     168           2 :     gtk_widget_set_can_focus(GTK_WIDGET(container), TRUE);
     169           2 :     gtk_container_set_resize_mode(GTK_CONTAINER(container), GTK_RESIZE_IMMEDIATE);
     170           2 :     gtk_widget_set_redraw_on_allocate(GTK_WIDGET(container), FALSE);
     171           2 : }
     172             : 
     173             : void
     174           1 : moz_container_map (GtkWidget *widget)
     175             : {
     176             :     MozContainer *container;
     177             :     GList *tmp_list;
     178             :     GtkWidget *tmp_child;
     179             : 
     180           1 :     g_return_if_fail (IS_MOZ_CONTAINER(widget));
     181           1 :     container = MOZ_CONTAINER (widget);
     182             : 
     183           1 :     gtk_widget_set_mapped(widget, TRUE);
     184             : 
     185           1 :     tmp_list = container->children;
     186           1 :     while (tmp_list) {
     187           0 :         tmp_child = ((MozContainerChild *)tmp_list->data)->widget;
     188             :     
     189           0 :         if (gtk_widget_get_visible(tmp_child)) {
     190           0 :             if (!gtk_widget_get_mapped(tmp_child))
     191           0 :                 gtk_widget_map(tmp_child);
     192             :         }
     193           0 :         tmp_list = tmp_list->next;
     194             :     }
     195             : 
     196           1 :     if (gtk_widget_get_has_window (widget)) {
     197           0 :         gdk_window_show (gtk_widget_get_window(widget));
     198             :     }
     199             : }
     200             : 
     201             : void
     202           0 : moz_container_unmap (GtkWidget *widget)
     203             : {
     204           0 :     g_return_if_fail (IS_MOZ_CONTAINER (widget));
     205             : 
     206           0 :     gtk_widget_set_mapped(widget, FALSE);
     207             : 
     208           0 :     if (gtk_widget_get_has_window (widget)) {
     209           0 :         gdk_window_hide (gtk_widget_get_window(widget));
     210             :     }
     211             : }
     212             : 
     213             : void
     214           2 : moz_container_realize (GtkWidget *widget)
     215             : {
     216           2 :     GdkWindow *parent = gtk_widget_get_parent_window (widget);
     217             :     GdkWindow *window;
     218             : 
     219           2 :     gtk_widget_set_realized(widget, TRUE);
     220             : 
     221           2 :     if (gtk_widget_get_has_window (widget)) {
     222             :         GdkWindowAttr attributes;
     223           0 :         gint attributes_mask = GDK_WA_VISUAL | GDK_WA_X | GDK_WA_Y;
     224             :         GtkAllocation allocation;
     225             : 
     226           0 :         gtk_widget_get_allocation (widget, &allocation);
     227           0 :         attributes.event_mask = gtk_widget_get_events (widget);
     228           0 :         attributes.x = allocation.x;
     229           0 :         attributes.y = allocation.y;
     230           0 :         attributes.width = allocation.width;
     231           0 :         attributes.height = allocation.height;
     232           0 :         attributes.wclass = GDK_INPUT_OUTPUT;
     233           0 :         attributes.visual = gtk_widget_get_visual (widget);
     234           0 :         attributes.window_type = GDK_WINDOW_CHILD;
     235             : 
     236             : #if (MOZ_WIDGET_GTK == 2)
     237             :         attributes.colormap = gtk_widget_get_colormap (widget);
     238             :         attributes_mask |= GDK_WA_COLORMAP;
     239             : #endif
     240             : 
     241           0 :         window = gdk_window_new (parent, &attributes, attributes_mask);
     242           0 :         gdk_window_set_user_data (window, widget);
     243             : #if (MOZ_WIDGET_GTK == 2)
     244             :         /* TODO GTK3? */
     245             :         /* set the back pixmap to None so that you don't end up with the gtk
     246             :            default which is BlackPixel */
     247             :         gdk_window_set_back_pixmap (window, NULL, FALSE);
     248             : #endif
     249             :     } else {
     250           2 :         window = parent;
     251           2 :         g_object_ref (window);
     252             :     }
     253             : 
     254           2 :     gtk_widget_set_window (widget, window);
     255             : 
     256             : #if (MOZ_WIDGET_GTK == 2)
     257             :     widget->style = gtk_style_attach (widget->style, widget->window);
     258             : #endif
     259           2 : }
     260             : 
     261             : void
     262           1 : moz_container_size_allocate (GtkWidget     *widget,
     263             :                              GtkAllocation *allocation)
     264             : {
     265             :     MozContainer   *container;
     266             :     GList          *tmp_list;
     267             :     GtkAllocation   tmp_allocation;
     268             : 
     269           1 :     g_return_if_fail (IS_MOZ_CONTAINER (widget));
     270             : 
     271             :     /*  printf("moz_container_size_allocate %p %d %d %d %d\n",
     272             :         (void *)widget,
     273             :         allocation->x,
     274             :         allocation->y,
     275             :         allocation->width,
     276             :         allocation->height); */
     277             : 
     278             :     /* short circuit if you can */
     279           1 :     container = MOZ_CONTAINER (widget);
     280           1 :     gtk_widget_get_allocation(widget, &tmp_allocation);
     281           2 :     if (!container->children &&
     282           1 :         tmp_allocation.x == allocation->x &&
     283           0 :         tmp_allocation.y == allocation->y &&
     284           0 :         tmp_allocation.width == allocation->width &&
     285           0 :         tmp_allocation.height == allocation->height) {
     286           0 :         return;
     287             :     }
     288             : 
     289           1 :     gtk_widget_set_allocation(widget, allocation);
     290             : 
     291           1 :     tmp_list = container->children;
     292             : 
     293           1 :     while (tmp_list) {
     294           0 :         MozContainerChild *child = static_cast<MozContainerChild*>(tmp_list->data);
     295             : 
     296           0 :         moz_container_allocate_child (container, child);
     297             : 
     298           0 :         tmp_list = tmp_list->next;
     299             :     }
     300             : 
     301           1 :     if (gtk_widget_get_has_window (widget) &&
     302           0 :         gtk_widget_get_realized (widget)) {
     303             : 
     304           0 :         gdk_window_move_resize(gtk_widget_get_window(widget),
     305             :                                allocation->x,
     306             :                                allocation->y,
     307             :                                allocation->width,
     308           0 :                                allocation->height);
     309             :     }
     310             : }
     311             : 
     312             : void
     313           0 : moz_container_remove (GtkContainer *container, GtkWidget *child_widget)
     314             : {
     315             :     MozContainerChild *child;
     316             :     MozContainer *moz_container;
     317             :     GdkWindow* parent_window;
     318             : 
     319           0 :     g_return_if_fail (IS_MOZ_CONTAINER(container));
     320           0 :     g_return_if_fail (GTK_IS_WIDGET(child_widget));
     321             : 
     322           0 :     moz_container = MOZ_CONTAINER(container);
     323             : 
     324           0 :     child = moz_container_get_child (moz_container, child_widget);
     325           0 :     g_return_if_fail (child);
     326             : 
     327             :     /* gtk_widget_unparent will remove the parent window (as well as the
     328             :      * parent widget), but, in Mozilla's window hierarchy, the parent window
     329             :      * may need to be kept because it may be part of a GdkWindow sub-hierarchy
     330             :      * that is being moved to another MozContainer.
     331             :      *
     332             :      * (In a conventional GtkWidget hierarchy, GdkWindows being reparented
     333             :      * would have their own GtkWidget and that widget would be the one being
     334             :      * reparented.  In Mozilla's hierarchy, the parent_window needs to be
     335             :      * retained so that the GdkWindow sub-hierarchy is maintained.)
     336             :      */
     337           0 :     parent_window = gtk_widget_get_parent_window(child_widget);
     338           0 :     if (parent_window)
     339           0 :         g_object_ref(parent_window);
     340             : 
     341           0 :     gtk_widget_unparent(child_widget);
     342             : 
     343           0 :     if (parent_window) {
     344             :         /* The child_widget will always still exist because g_signal_emit,
     345             :          * which invokes this function, holds a reference.
     346             :          *
     347             :          * If parent_window is the container's root window then it will not be
     348             :          * the parent_window if the child_widget is placed in another
     349             :          * container.
     350             :          */
     351           0 :         if (parent_window != gtk_widget_get_window(GTK_WIDGET(container)))
     352           0 :             gtk_widget_set_parent_window(child_widget, parent_window);
     353             : 
     354           0 :         g_object_unref(parent_window);
     355             :     }
     356             : 
     357           0 :     moz_container->children = g_list_remove(moz_container->children, child);
     358           0 :     g_free(child);
     359             : }
     360             : 
     361             : void
     362           7 : moz_container_forall (GtkContainer *container, gboolean include_internals,
     363             :                       GtkCallback  callback, gpointer callback_data)
     364             : {
     365             :     MozContainer *moz_container;
     366             :     GList *tmp_list;
     367             :   
     368           7 :     g_return_if_fail (IS_MOZ_CONTAINER(container));
     369           7 :     g_return_if_fail (callback != NULL);
     370             : 
     371           7 :     moz_container = MOZ_CONTAINER(container);
     372             : 
     373           7 :     tmp_list = moz_container->children;
     374           7 :     while (tmp_list) {
     375             :         MozContainerChild *child;
     376           0 :         child = static_cast<MozContainerChild*>(tmp_list->data);
     377           0 :         tmp_list = tmp_list->next;
     378           0 :         (* callback) (child->widget, callback_data);
     379             :     }
     380             : }
     381             : 
     382             : static void
     383           0 : moz_container_allocate_child (MozContainer *container,
     384             :                               MozContainerChild *child)
     385             : {
     386             :     GtkAllocation  allocation;
     387             : 
     388           0 :     gtk_widget_get_allocation (child->widget, &allocation);
     389           0 :     allocation.x = child->x;
     390           0 :     allocation.y = child->y;
     391             : 
     392           0 :     gtk_widget_size_allocate (child->widget, &allocation);
     393           0 : }
     394             : 
     395             : MozContainerChild *
     396           0 : moz_container_get_child (MozContainer *container, GtkWidget *child_widget)
     397             : {
     398             :     GList *tmp_list;
     399             : 
     400           0 :     tmp_list = container->children;
     401           0 :     while (tmp_list) {
     402             :         MozContainerChild *child;
     403             :     
     404           0 :         child = static_cast<MozContainerChild*>(tmp_list->data);
     405           0 :         tmp_list = tmp_list->next;
     406             : 
     407           0 :         if (child->widget == child_widget)
     408           0 :             return child;
     409             :     }
     410             : 
     411           0 :     return NULL;
     412             : }
     413             : 
     414             : static void 
     415           0 : moz_container_add(GtkContainer *container, GtkWidget *widget)
     416             : {
     417           0 :     moz_container_put(MOZ_CONTAINER(container), widget, 0, 0);
     418           0 : }

Generated by: LCOV version 1.13