Skip to content

Commit

Permalink
Stop using deprecated [GdkPixbuf.from_xpm_data]
Browse files Browse the repository at this point in the history
This function can fail at runtime with certain versions of gdk-pixbuf.

Replace it with an XPM parsing function created specifically for the
icon data in the Pixmaps module.
  • Loading branch information
tleedjarv committed May 7, 2024
1 parent 9786ebb commit 941b19b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
57 changes: 57 additions & 0 deletions src/pixmaps.ml
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,63 @@ let copyBAblack_asym = [|
|]


(***********************************************************************)
(* XPM parse function *)
(***********************************************************************)

(* This function is not for universal XPM parsing. It is intended only
for parsing the icon definitions above in this file.
Do not use [GdkPixbuf.from_xpm_data] as it has been removed from
upstream gdk-pixbuf. *)
let to_pixbuf dat =
let colormap = Array.make 256 [| 0; 0; 0; 0 |] in
let getColor ch = colormap.(Char.code ch) in
let setColor ch col =
colormap.(Char.code ch) <-
[| (col asr 16) land 0xff;
(col asr 8) land 0xff;
(col asr 0) land 0xff;
0xff |]
in

(* width height num_colors chars_per_pixel *)
let parseValues w h nc chp =
(* Very basic sanity checks *)
if w < 1 || w > 128 || h < 1 || h > 128 || nc < 1 || nc > 256 || chp <> 1 then
invalid_arg "XPM: Unsupported header values";
w, h, nc
in
let width, height, colors = Scanf.sscanf dat.(0) " %u %u %u %u" parseValues in

let parseColor ch t s =
if t <> 'c' then invalid_arg "XPM: Unsupported color type";
if s <> "None" then begin
if s = "" || s.[0] <> '#' then invalid_arg "XPM: Unsupported color code";
Scanf.sscanf s "#%x" (setColor ch)
end
in
for i = 1 to colors do
Scanf.sscanf dat.(i) "%c %c %s" parseColor
done;

let p = GdkPixbuf.create ~width ~height ~has_alpha:true () in
let pixels = GdkPixbuf.get_pixels p in
let setPixel pos v =
let pos = pos * 4 in
Gpointer.set_byte pixels ~pos:(pos + 0) v.(0);
Gpointer.set_byte pixels ~pos:(pos + 1) v.(1);
Gpointer.set_byte pixels ~pos:(pos + 2) v.(2);
Gpointer.set_byte pixels ~pos:(pos + 3) v.(3)
in
let pxlStart = colors + 1 in
for i = 0 to height - 1 do
for j = 0 to width - 1 do
setPixel (i * width + j) (getColor dat.(pxlStart + i).[j])
done
done;
p


(***********************************************************************)
(* Unison icon *)
(***********************************************************************)
Expand Down
2 changes: 1 addition & 1 deletion src/uigtk3.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3293,7 +3293,7 @@ let createToplevelWindow () =
let blackPixel = "000000" in
*)
let buildPixmap p =
GdkPixbuf.from_xpm_data p in
Pixmaps.to_pixbuf p in
let buildPixmaps f c1 =
(buildPixmap (f c1), buildPixmap (f lightbluePixel)) in
Expand Down

0 comments on commit 941b19b

Please sign in to comment.