2
2
3
3
#include < gdkmm.h>
4
4
5
- template <class T >
6
- static void iterTo (Glib::VariantIter & iter, T & to)
5
+ namespace
7
6
{
8
- Glib::Variant<T> var;
9
- iter.next_value (var);
10
- to = var.get ();
7
+ template <class ... T>
8
+ void extractValues (const Glib::VariantBase & variant, T&... values)
9
+ {
10
+ std::tie (values...) = Glib::VariantBase::cast_dynamic<Glib::Variant<std::tuple<T...>>>(variant).get ();
11
11
}
12
12
13
13
template <class K >
14
- static K getHint (const std::map<std::string, Glib::VariantBase> & map, const std::string & key)
14
+ K getHint (const std::map<std::string, Glib::VariantBase> & map, const std::string & key)
15
15
{
16
16
if (map.count (key) != 0 )
17
17
{
18
18
const auto & val = map.at (key);
19
19
if (val.is_of_type (Glib::Variant<K>::variant_type ()))
20
20
{
21
- return Glib::VariantBase::cast_dynamic<Glib::Variant<K>>(map. at (key) ).get ();
21
+ return Glib::VariantBase::cast_dynamic<Glib::Variant<K>>(val ).get ();
22
22
}
23
23
}
24
24
@@ -27,41 +27,29 @@ static K getHint(const std::map<std::string, Glib::VariantBase> & map, const std
27
27
28
28
Glib::RefPtr<Gdk::Pixbuf> pixbufFromVariant (const Glib::VariantBase & variant)
29
29
{
30
- if (!variant.is_of_type (Glib::VariantType (" iiibiiay" )))
31
- {
32
- throw std::invalid_argument (" Cannot create pixbuf from variant." );
33
- }
34
-
35
- auto iter = Glib::VariantIter (variant);
36
30
gint32 width;
37
31
gint32 height;
38
32
gint32 rowstride;
39
33
bool has_alpha;
40
34
gint32 bits_per_sample;
41
35
gint32 channels;
42
-
43
- iterTo (iter, width);
44
- iterTo (iter, height);
45
- iterTo (iter, rowstride);
46
- iterTo (iter, has_alpha);
47
- iterTo (iter, bits_per_sample);
48
- iterTo (iter, channels);
49
-
50
- Glib::VariantBase data_var;
51
- iter.next_value (data_var);
36
+ std::vector<guint8> data;
37
+ extractValues (variant, width, height, rowstride, has_alpha, bits_per_sample, channels, data);
52
38
53
39
// for integer positive A, floor((A + 7) / 8) = ceil(A / 8)
54
40
gulong pixel_size = (channels * bits_per_sample + 7 ) / 8 ;
55
- if (data_var. get_size () != ((gulong)height - 1 ) * (gulong)rowstride + (gulong)width * pixel_size)
41
+ if (data. size () != ((gulong)height - 1 ) * (gulong)rowstride + (gulong)width * pixel_size)
56
42
{
57
43
throw std::invalid_argument (
58
44
" Cannot create pixbuf from variant: expected data size doesn't equal actual one." );
59
45
}
60
46
61
- const auto *data = (guint8*)(g_memdup2 (data_var.get_data (), data_var.get_size ()));
62
- return Gdk::Pixbuf::create_from_data (data, Gdk::COLORSPACE_RGB, has_alpha, bits_per_sample, width, height,
63
- rowstride);
47
+ auto *data_ptr = new auto (std::move (data));
48
+ return Gdk::Pixbuf::create_from_data (data_ptr->data (),
49
+ Gdk::COLORSPACE_RGB, has_alpha, bits_per_sample, width, height,
50
+ rowstride, [data_ptr] (auto *) { delete data_ptr; });
64
51
}
52
+ } // namespace
65
53
66
54
Notification::Hints::Hints (const std::map<std::string, Glib::VariantBase> & map)
67
55
{
@@ -73,7 +61,7 @@ Notification::Hints::Hints(const std::map<std::string, Glib::VariantBase> & map)
73
61
image_data = pixbufFromVariant (map.at (" image-data" ));
74
62
} else if (map.count (" icon_data" ) != 0 )
75
63
{
76
- image_data = pixbufFromVariant (map.at (" image_data " ));
64
+ image_data = pixbufFromVariant (map.at (" icon_data " ));
77
65
}
78
66
79
67
image_path = getHint<Glib::ustring>(map, " image-path" );
@@ -94,29 +82,13 @@ Notification::Hints::Hints(const std::map<std::string, Glib::VariantBase> & map)
94
82
95
83
Notification::Notification (const Glib::VariantContainerBase & parameters, const Glib::ustring & sender)
96
84
{
97
- static const auto REQUIRED_TYPE = Glib::VariantType (" (susssasa{sv}i)" );
98
- if (!parameters.is_of_type (REQUIRED_TYPE))
99
- {
100
- throw std::invalid_argument (" NotificationInfo: parameters type must be (susssasa{sv}i)" );
101
- }
102
-
103
- Glib::VariantBase params_var;
104
- parameters.get_normal_form (params_var);
105
- auto iter = Glib::VariantIter (params_var);
106
- iterTo (iter, app_name);
107
- iterTo (iter, id);
85
+ std::map<std::string, Glib::VariantBase> hints_map;
86
+ extractValues (parameters, app_name, id, app_icon, summary, body, actions, hints_map, expire_time);
108
87
if (id == 0 )
109
88
{
110
89
id = ++Notification::notifications_count;
111
90
}
112
91
113
- iterTo (iter, app_icon);
114
- iterTo (iter, summary);
115
- iterTo (iter, body);
116
- iterTo (iter, actions);
117
-
118
- std::map<std::string, Glib::VariantBase> hints_map;
119
- iterTo (iter, hints_map);
120
92
hints = Hints (hints_map);
121
93
122
94
additional_info.recv_time = std::time (nullptr );
0 commit comments