1/*
2 * Copyright (C) 2011, 2012 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "WebKitAccessibleInterfaceValue.h"
22
23#if HAVE(ACCESSIBILITY)
24
25#include "AccessibilityObject.h"
26#include "HTMLNames.h"
27#include "WebKitAccessibleWrapperAtk.h"
28
29using namespace WebCore;
30
31static AccessibilityObject* core(AtkValue* value)
32{
33    if (!WEBKIT_IS_ACCESSIBLE(value))
34        return 0;
35
36    return webkitAccessibleGetAccessibilityObject(WEBKIT_ACCESSIBLE(value));
37}
38
39static void webkitAccessibleValueGetCurrentValue(AtkValue* value, GValue* gValue)
40{
41    memset(gValue,  0, sizeof(GValue));
42    g_value_init(gValue, G_TYPE_FLOAT);
43    g_value_set_float(gValue, core(value)->valueForRange());
44}
45
46static void webkitAccessibleValueGetMaximumValue(AtkValue* value, GValue* gValue)
47{
48    memset(gValue,  0, sizeof(GValue));
49    g_value_init(gValue, G_TYPE_FLOAT);
50    g_value_set_float(gValue, core(value)->maxValueForRange());
51}
52
53static void webkitAccessibleValueGetMinimumValue(AtkValue* value, GValue* gValue)
54{
55    memset(gValue,  0, sizeof(GValue));
56    g_value_init(gValue, G_TYPE_FLOAT);
57    g_value_set_float(gValue, core(value)->minValueForRange());
58}
59
60static gboolean webkitAccessibleValueSetCurrentValue(AtkValue* value, const GValue* gValue)
61{
62    double newValue;
63    if (G_VALUE_HOLDS_DOUBLE(gValue))
64        newValue = g_value_get_double(gValue);
65    else if (G_VALUE_HOLDS_FLOAT(gValue))
66        newValue = g_value_get_float(gValue);
67    else if (G_VALUE_HOLDS_INT64(gValue))
68        newValue = g_value_get_int64(gValue);
69    else if (G_VALUE_HOLDS_INT(gValue))
70        newValue = g_value_get_int(gValue);
71    else if (G_VALUE_HOLDS_LONG(gValue))
72        newValue = g_value_get_long(gValue);
73    else if (G_VALUE_HOLDS_ULONG(gValue))
74        newValue = g_value_get_ulong(gValue);
75    else if (G_VALUE_HOLDS_UINT64(gValue))
76        newValue = g_value_get_uint64(gValue);
77    else if (G_VALUE_HOLDS_UINT(gValue))
78        newValue = g_value_get_uint(gValue);
79    else
80        return false;
81
82    AccessibilityObject* coreObject = core(value);
83    if (!coreObject->canSetValueAttribute())
84        return FALSE;
85
86    // Check value against range limits
87    newValue = std::max(static_cast<double>(coreObject->minValueForRange()), newValue);
88    newValue = std::min(static_cast<double>(coreObject->maxValueForRange()), newValue);
89
90    coreObject->setValue(String::number(newValue));
91    return TRUE;
92}
93
94static void webkitAccessibleValueGetMinimumIncrement(AtkValue* value, GValue* gValue)
95{
96    memset(gValue,  0, sizeof(GValue));
97    g_value_init(gValue, G_TYPE_FLOAT);
98
99    AccessibilityObject* coreObject = core(value);
100    if (!coreObject->getAttribute(HTMLNames::stepAttr).isEmpty()) {
101        g_value_set_float(gValue, coreObject->stepValueForRange());
102        return;
103    }
104
105    // If 'step' attribute is not defined, WebCore assumes a 5% of the
106    // range between minimum and maximum values, so return that.
107    float range = coreObject->maxValueForRange() - coreObject->minValueForRange();
108    g_value_set_float(gValue, range * 0.05);
109}
110
111void webkitAccessibleValueInterfaceInit(AtkValueIface* iface)
112{
113    iface->get_current_value = webkitAccessibleValueGetCurrentValue;
114    iface->get_maximum_value = webkitAccessibleValueGetMaximumValue;
115    iface->get_minimum_value = webkitAccessibleValueGetMinimumValue;
116    iface->set_current_value = webkitAccessibleValueSetCurrentValue;
117    iface->get_minimum_increment = webkitAccessibleValueGetMinimumIncrement;
118}
119
120#endif
121