naughty: Correctly handle rowstride on icons

The notification spec allow sending icons as data with a dbus message. The
rowstride for this can be set which means there can be bytes after each row of
icon data which must be ignored.

Before this commit, naughty wasn't properly ignoring these garbage bytes which
resulted in weird notifications.

Thanks to dadrc for reporting that gmusicbrowser's notifications didn't work.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2012-11-17 21:37:40 +01:00
parent 882099f900
commit ee46c9e5ae
1 changed files with 23 additions and 11 deletions

View File

@ -538,25 +538,37 @@ if capi.dbus then
-- icon_data is an array: -- icon_data is an array:
-- 1 -> width, 2 -> height, 3 -> rowstride, 4 -> has alpha -- 1 -> width, 2 -> height, 3 -> rowstride, 4 -> has alpha
-- 5 -> bits per sample, 6 -> channels, 7 -> data -- 5 -> bits per sample, 6 -> channels, 7 -> data
local width, height, rowstride = hints.icon_data[1], hints.icon_data[2], hints.icon_data[3]
local imgdata = "" local imgdata = ""
local format, bpp
-- If has alpha (ARGB32) -- If has alpha (ARGB32)
if hints.icon_data[6] == 4 then if hints.icon_data[6] == 4 then
for i = 1, #hints.icon_data[7], 4 do format, bpp = cairo.Format.ARGB32, 4
imgdata = imgdata .. hints.icon_data[7]:sub(i, i + 2):reverse()
imgdata = imgdata .. hints.icon_data[7]:sub(i + 3, i + 3)
end
-- If has not alpha (RGB24) -- If has not alpha (RGB24)
elseif hints.icon_data[6] == 3 then elseif hints.icon_data[6] == 3 then
for i = 1, #hints.icon_data[7], 3 do format, bpp = cairo.Format.RGB24, 3
end
-- Figure out some stride magic (cairo dictates rowstride)
local stride = cairo.Format.stride_for_width(format, width)
local append = string.format("%c", 0):rep(stride - 4 * width)
local offset = 0
-- Now convert each row on its own
for y = 1, height do
for i = 1 + offset, width * bpp + offset, bpp do
imgdata = imgdata .. hints.icon_data[7]:sub(i, i + 2):reverse() imgdata = imgdata .. hints.icon_data[7]:sub(i, i + 2):reverse()
imgdata = imgdata .. string.format("%c", 255) -- alpha is 255 if bpp == 4 then
imgdata = imgdata .. hints.icon_data[7]:sub(i + 3, i + 3)
else
imgdata = imgdata .. string.format("%c", 255)
end end
end end
if imgdata then -- Handle rowstride, offset is stride for the input, append for output
args.icon = cairo.ImageSurface.create_for_data(imgdata, offset = offset + rowstride
cairo.Format.ARGB32, hints.icon_data[1], hints.icon_data[2], hints.icon_data[1] * 4) imgdata = imgdata .. append
end end
args.icon = cairo.ImageSurface.create_for_data(imgdata, format,
width, height, stride)
end end
if replaces_id and replaces_id ~= "" and replaces_id ~= 0 then if replaces_id and replaces_id ~= "" and replaces_id ~= 0 then
args.replaces_id = replaces_id args.replaces_id = replaces_id