18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/skin/composer.h"
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stddef.h>
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/system.h"
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* forwards */
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void  skin_plate_get_region       ( SkinPlate*  p, SkinRegion  *pregion );
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void  skin_plate_get_opaque_region( SkinPlate*  p, SkinRegion  *pregion );
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* recompute region if needed */
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_ensure_region( SkinPlate*  p )
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p->any.type == SKIN_PLATE_SURFACE || p->group.hasRegion)
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  n, count = areflist_count( p->group.children );
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_reset(p->any.region);
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (n = 0; n < count; n++) {
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SkinRegion  r[1];
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SkinPlate*  child = areflist_get( p->group.children, n );
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_plate_get_region( child, r );
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_translate( r, child->any.pos.x, child->any.pos.y );
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_union( p->any.region, r );
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p->group.hasRegion = 1;
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return region in 'region' */
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_get_region( SkinPlate*  p, SkinRegion*  region )
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( p->any.type != SKIN_PLATE_SURFACE && !p->group.hasRegion ) {
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_plate_ensure_region(p);
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_copy( region, p->any.region );
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* recompute opaque region is needed */
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_ensure_opaque_region( SkinPlate*  p )
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p->any.type != SKIN_PLATE_SURFACE && !p->group.hasOpaqueRegion) {
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  n, count = areflist_count( p->group.children );
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_reset(p->group.opaqueRegion);
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (n = 0; n < count; n++) {
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SkinRegion  r[1];
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SkinPlate*  child = areflist_get( p->group.children, n );
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_plate_get_opaque_region(child, r);
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_translate(r, child->any.pos.x, child->any.pos.y);
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_union( p->group.opaqueRegion, r);
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p->group.hasOpaqueRegion = 1;
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return opaque pixels region */
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_get_opaque_region( SkinPlate*  p, SkinRegion  *pregion )
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( p->any.type == SKIN_PLATE_SURFACE ) {
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p->any.isOpaque)
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_init_copy(pregion, p->any.region);
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_reset(pregion);
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_plate_ensure_opaque_region(p);
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_copy(pregion, p->group.opaqueRegion);
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* invalidate region in parent groups */
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_invalidate_parent( SkinPlate*  p )
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!p->any.isVisible)
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (p) {
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p->any.type != SKIN_PLATE_SURFACE) {
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p->group.hasRegion       = 0;
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p->group.hasOpaqueRegion = 0;
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = p->any.parent;
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_invalidate_( SkinPlate*  p, SkinRegion*  r, SkinPlate*  child )
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p->any.type != SKIN_PLATE_SURFACE) {
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  n = areflist_count( p->group.children );
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (child != NULL) {
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            n = areflist_indexOf( p->group.children, child );
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (n > 0) {
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            n -= 1;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            child = areflist_get( p->group.children, n );
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_translate( r, child->any.pos.x, child->any.pos.y );
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_plate_invalidate_( p, r, NULL );
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_translate( r, -child->any.pos.x, -child->any.pos.y );
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (skin_region_is_empty(r))
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return;
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p->any.type != SKIN_PLATE_SPACE) {
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SkinPlate*  parent = p->any.parent;
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_translate(r, parent->any.pos.x, parent->any.pos.y );
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_plate_invalidate_(parent, r, p);
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* send to viewports */
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  n, count = areflist_count( p->space.viewports );
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (n = 0; n < count; n++) {
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                SkinViewport*  v = areflist_get( p->space.viewports, n );
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                skin_viewport_invalidate(v, r);
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_invalidate_region( SkinPlate*  p )
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r[1];
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_plate_get_region( p, r );
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_plate_invalidate_(p->any.parent, r, p);
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset(r);
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* change visibility */
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_set_visible( SkinPlate*  p, int  isVisible )
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    isVisible = !!isVisible;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (isVisible == p->any.isVisible)
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_plate_invalidate_parent(p);
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_plate_invalidate_region(p);
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.isVisible = isVisible;
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_set_opaque( SkinPlate*  p, int  isOpaque )
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    isOpaque = !!isOpaque;
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (isOpaque == p->any.isOpaque)
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_plate_invalidate_parent(p);
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_plate_invalidate_region(p);
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.isOpaque = isOpaque;
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern SkinPlate*
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_surface( SkinPlate*         parent,
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    SkinPos*           pos,
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    SkinRegion*        region,
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    void*              surface,
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    SkinPlateDrawFunc  draw,
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    SkinPlateDoneFunc  done )
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinPlate*  p;
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ANEW0(p);
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.type      = SKIN_PLATE_SURFACE;
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.parent    = parent;
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.pos.x     = pos->x;
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.pos.y     = pos->y;
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.isVisible = 1;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.isOpaque  = 1;
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_copy( p->any.region, region );
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return p;
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinPlate*
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_group( SkinPlate*  parent, SkinPos*  pos )
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r[1];
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinPlate*  p;
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset(r);
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p = skin_plate_surface( parent, pos, r, NULL, NULL, NULL );
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.type              = SKIN_PLATE_GROUP;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->group.hasOpaqueRegion = 0;
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_empty( p->group.opaqueRegion );
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    areflist_init( p->group.children );
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return p;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinPlate*
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_space( void )
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinPos     pos;
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinPlate*  p;
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pos.x       = pos.y = 0;
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p           = skin_plate_group( NULL, &pos );
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p->any.type = SKIN_PLATE_SPACE;
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    areflist_init( p->space.viewports );
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return p;
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_free( SkinPlate*  p )
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p->any.type >= SKIN_PLATE_SPACE) {
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while ( areflist_count( p->space.viewports ) )
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_viewport_free( areflist_get( p->space.viewports, 0 ) );
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p->any.type >= SKIN_PLATE_GROUP) {
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_reset( p->group.opaqueRegion );
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p->group.hasOpaqueRegion = 0;
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p->group.hasRegion       = 0;
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while ( areflist_count( p->group.children ) )
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_plate_free( areflist_get( p->group.children, 0 ) );
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p->any.type == SKIN_PLATE_SURFACE) {
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p->surface.done)
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p->surface.done( p->surface.user );
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset( p->any.region );
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p->any.parent) {
2574c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        areflist_delFirst( p->any.parent->group.children, p );
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_invalidate( SkinPlate*  plate, SkinRegion*  region )
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r[1];
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_copy( r, region );
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* we use two regions to manage the front-to-back composition here
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  'updated' initially contains the update region, in parent coordinates
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  'drawn'   is initially empty, and will be filled with the region of translucent
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *            pixels that have been
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  for a given surface plate, we translate the regions to plate coordinates,
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  then we do an opaque blit of 'intersection(updated,region)', then removing it from 'updated'
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  after that, we make a DSTOVER blit of 'intersection(drawn,region)'
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  if the plate is not opaque, we add this intersection to 'drawn'
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_redraw( SkinPlate*  plate, SkinRegion*  updated, SkinRegion*  drawn, SkinPos*  apos, SkinViewport*  viewport )
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinPos  pos = plate->any.pos;
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!plate->any.isVisible)
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (skin_region_is_empty(updated) && skin_region_is_empty(drawn))
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* translate regions to plate coordinates */
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_translate( updated, pos.x, pos.y );
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_translate( drawn,   pos.y, pos.y );
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    apos->x += pos.x;
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    apos->y += pos.y;
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (plate->any.type == SKIN_PLATE_SURFACE) {
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinRegion  r[1];
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* inter(updated,region) => opaque blit + remove 'region' from 'updated'*/
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_plate_get_region(plate, r);
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_intersect(r, updated);
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!skin_region_is_empty(r)) {
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            plate->surface.draw( plate->surface.user, r, apos, viewport, 1 );
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_substract(updated, r);
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_reset(r);
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* inter(drawn,region) => DSTOVER blit + if non-opaque add it to 'drawn' */
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_plate_get_region(plate, r);
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_intersect(r, drawn);
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!skin_region_is_empty(r)) {
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            plate->surface.draw( plate->surface.user, r, apos, viewport, 0);
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!plate->any.isOpaque)
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                skin_region_union(drawn, r);
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_region_reset(r);
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  n, count = areflist_count(plate->group.children);
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (n = 0; n < count; n++) {
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SkinPos  pos;
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pos.x = apos->x + plate->any.pos.x;
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pos.y = apos->y + plate->any.pos.y;
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_plate_redraw( areflist_get(plate->group.children, n ), updated, drawn, &pos, viewport );
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (skin_region_is_empty(updated) && skin_region_is_empty(drawn))
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* convert back to parent coordinates */
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    apos->x -= pos.x;
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    apos->y -= pos.y;
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_translate( updated, -pos.x, -pos.y );
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_translate( drawn,   -pos.x, -pos.y );
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern SkinViewport*
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_viewport( SkinPlate*  space, SkinRect*  rect, void*  surface, int  sx, int  sy )
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinViewport*  v;
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ANEW0(v);
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v->space   = space;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v->rect    = rect[0];
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v->spos.x  = sx;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v->spos.y  = sy;
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v->surface = surface;
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_empty( v->update );
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return v;
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_viewport_free( SkinViewport*  v )
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinPlate*  space = v->space;
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (space != NULL) {
3654c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        areflist_delFirst( space->space.viewports, v );
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        v->space = NULL;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset( v->update );
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AFREE(v);
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_viewport_invalidate( SkinViewport*  v, SkinRegion*  region )
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r[1];
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_copy(r,region);
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_translate(r, -v->spos.x, -v->spos.y);
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_intersect_rect(r,&v->rect);
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_union( v->update, r );
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset(r);
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_viewport_redraw( SkinViewport*  v )
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (v->space && !skin_region_is_empty(v->update)) {
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinRegion  update[1];
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinRegion  drawn[1];
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinPos     apos;
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_copy(update, v->update);
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_reset(drawn);
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_reset( v->update );
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        apos.x = apos.y = 0;
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_plate_redraw( v->space, update, drawn, &apos, v );
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_reset(update);
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_reset(drawn);
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
402