Bug Summary

File:rc/gs-fade.c
Warning:line 511, column 47
Access of the heap area at index 0, while it holds only 0 'struct GSGammaInfo' element

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gs-fade.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/src -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -I . -I . -D CAFEMENU_I_KNOW_THIS_IS_UNSTABLE -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/cafe-menus -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/cafe-menus -D PREFIX="/usr" -D BINDIR="/usr/bin" -D LIBDIR="/usr/lib" -D LIBEXECDIR="/usr/libexec" -D DATADIR="/usr/share" -D SYSCONFDIR="/usr/etc" -D CAFELOCALEDIR="/usr/share/locale" -D SAVERDIR="/usr/libexec/cafe-screensaver" -D THEMESDIR="/usr/share/cafe-screensaver/themes" -D CTKBUILDERDIR="/usr/share/cafe-screensaver" -D PAM_SERVICE_NAME="cafe-screensaver" -D G_DISABLE_ASSERT -D G_DISABLE_CHECKS -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/libxml2 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libpng16 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/libmount -I /usr/include/blkid -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2025-01-09-133151-52719-1 -x c gs-fade.c
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2004-2009 William Jon McCann <mccann@jhu.edu>
4 * Copyright (C) 2009 Red Hat, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 * Authors: William Jon McCann <mccann@jhu.edu>
21 *
22 */
23
24#include "config.h"
25
26#include <stdlib.h>
27#include <stdio.h>
28#include <time.h>
29#include <errno(*__errno_location ()).h>
30
31#include <string.h>
32#include <sys/time.h>
33#include <sys/types.h>
34#ifdef HAVE_UNISTD_H1
35#include <unistd.h>
36#endif /* HAVE_UNISTD_H */
37
38#include <cdk/cdkx.h>
39#include <ctk/ctk.h>
40
41#include "gs-fade.h"
42#include "gs-debug.h"
43
44#define CAFE_DESKTOP_USE_UNSTABLE_API
45
46#include "libcafe-desktop/cafe-rr.h"
47
48/* XFree86 4.x+ Gamma fading */
49
50
51#ifdef HAVE_XF86VMODE_GAMMA1
52
53#include <X11/extensions/xf86vmode.h>
54
55#define XF86_MIN_GAMMA0.1 0.1
56
57#endif /* HAVE_XF86VMODE_GAMMA */
58
59static void gs_fade_finalize (GObject *object);
60
61struct GSGammaInfo
62{
63 int size;
64 unsigned short *r;
65 unsigned short *g;
66 unsigned short *b;
67};
68
69struct GSFadeScreenPrivate
70{
71 int fade_type;
72 int num_ramps;
73 /* one per crtc in randr mode */
74 struct GSGammaInfo *info;
75 /* one per screen in theory */
76 CafeRRScreen *rrscreen;
77#ifdef HAVE_XF86VMODE_GAMMA1
78 /* one per screen also */
79 XF86VidModeGamma vmg;
80#endif /* HAVE_XF86VMODE_GAMMA */
81 gboolean (*fade_setup) (GSFade *fade);
82 gboolean (*fade_set_alpha_gamma) (GSFade *fade,
83 gdouble alpha);
84 void (*fade_finish) (GSFade *fade);
85};
86
87struct GSFadePrivate
88{
89 guint enabled : 1;
90 guint active : 1;
91
92 guint timeout;
93
94 guint step;
95 guint num_steps;
96 guint timer_id;
97
98 gdouble alpha_per_iter;
99 gdouble current_alpha;
100
101 struct GSFadeScreenPrivate screen_priv;
102};
103
104enum
105{
106 FADED,
107 LAST_SIGNAL
108};
109
110enum
111{
112 FADE_TYPE_NONE,
113 FADE_TYPE_GAMMA_NUMBER,
114 FADE_TYPE_GAMMA_RAMP,
115 FADE_TYPE_XRANDR,
116};
117
118static guint signals [LAST_SIGNAL] = { 0, };
119
120G_DEFINE_TYPE_WITH_PRIVATE (GSFade, gs_fade, G_TYPE_OBJECT)static void gs_fade_init (GSFade *self); static void gs_fade_class_init
(GSFadeClass *klass); static GType gs_fade_get_type_once (void
); static gpointer gs_fade_parent_class = ((void*)0); static gint
GSFade_private_offset; static void gs_fade_class_intern_init
(gpointer klass) { gs_fade_parent_class = g_type_class_peek_parent
(klass); if (GSFade_private_offset != 0) g_type_class_adjust_private_offset
(klass, &GSFade_private_offset); gs_fade_class_init ((GSFadeClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
gs_fade_get_instance_private (GSFade *self) { return (((gpointer
) ((guint8*) (self) + (glong) (GSFade_private_offset)))); } GType
gs_fade_get_type (void) { static GType static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= gs_fade_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType gs_fade_get_type_once (void) { GType
g_define_type_id = g_type_register_static_simple (((GType) (
(20) << (2))), g_intern_static_string ("GSFade"), sizeof
(GSFadeClass), (GClassInitFunc)(void (*)(void)) gs_fade_class_intern_init
, sizeof (GSFade), (GInstanceInitFunc)(void (*)(void)) gs_fade_init
, (GTypeFlags) 0); { {{ GSFade_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (GSFadePrivate)); };} } return g_define_type_id
; }
121
122static gpointer fade_object = NULL((void*)0);
123
124#ifdef HAVE_XF86VMODE_GAMMA1
125
126/* This is needed because the VidMode extension doesn't work
127 on remote displays -- but if the remote display has the extension
128 at all, XF86VidModeQueryExtension returns true, and then
129 XF86VidModeQueryVersion dies with an X error.
130*/
131
132static gboolean error_handler_hit = FALSE(0);
133
134static int
135ignore_all_errors_ehandler (Display *dpy,
136 XErrorEvent *error)
137{
138 error_handler_hit = TRUE(!(0));
139
140 return 0;
141}
142
143static Boolint
144safe_XF86VidModeQueryVersion (Display *dpy,
145 int *majP,
146 int *minP)
147{
148 Boolint result;
149 XErrorHandler old_handler;
150
151 XSync (dpy, False0);
152 error_handler_hit = FALSE(0);
153 old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
154
155 result = XF86VidModeQueryVersion (dpy, majP, minP);
156
157 XSync (dpy, False0);
158 XSetErrorHandler (old_handler);
159 XSync (dpy, False0);
160
161 return (error_handler_hit
162 ? False0
163 : result);
164}
165
166static gboolean
167xf86_whack_gamma (int screen,
168 struct GSFadeScreenPrivate *screen_priv,
169 float ratio)
170{
171 Boolint status;
172 struct GSGammaInfo *gamma_info;
173 CdkDisplay *display;
174
175 gamma_info = screen_priv->info;
176
177 if (!gamma_info)
178 return FALSE(0);
179
180 if (ratio < 0)
181 {
182 ratio = 0;
183 }
184 if (ratio > 1)
185 {
186 ratio = 1;
187 }
188
189 if (gamma_info->size == 0)
190 {
191 /* we only have a gamma number, not a ramp. */
192
193 XF86VidModeGamma g2;
194
195 g2.red = screen_priv->vmg.red * ratio;
196 g2.green = screen_priv->vmg.green * ratio;
197 g2.blue = screen_priv->vmg.blue * ratio;
198
199 if (g2.red < XF86_MIN_GAMMA0.1)
200 {
201 g2.red = XF86_MIN_GAMMA0.1;
202 }
203 if (g2.green < XF86_MIN_GAMMA0.1)
204 {
205 g2.green = XF86_MIN_GAMMA0.1;
206 }
207 if (g2.blue < XF86_MIN_GAMMA0.1)
208 {
209 g2.blue = XF86_MIN_GAMMA0.1;
210 }
211
212 status = XF86VidModeSetGamma (CDK_DISPLAY_XDISPLAY (cdk_display_get_default ())(cdk_x11_display_get_xdisplay (cdk_display_get_default ())), screen, &g2);
213 }
214 else
215 {
216
217# ifdef HAVE_XF86VMODE_GAMMA_RAMP1
218 unsigned short *r, *g, *b;
219 int i;
220
221 r = g_new0 (unsigned short, gamma_info->size)((unsigned short *) g_malloc0_n ((gamma_info->size), sizeof
(unsigned short)))
;
222 g = g_new0 (unsigned short, gamma_info->size)((unsigned short *) g_malloc0_n ((gamma_info->size), sizeof
(unsigned short)))
;
223 b = g_new0 (unsigned short, gamma_info->size)((unsigned short *) g_malloc0_n ((gamma_info->size), sizeof
(unsigned short)))
;
224
225 for (i = 0; i < gamma_info->size; i++)
226 {
227 r[i] = gamma_info->r[i] * ratio;
228 g[i] = gamma_info->g[i] * ratio;
229 b[i] = gamma_info->b[i] * ratio;
230 }
231
232 status = XF86VidModeSetGammaRamp (CDK_DISPLAY_XDISPLAY (cdk_display_get_default ())(cdk_x11_display_get_xdisplay (cdk_display_get_default ())), screen, gamma_info->size, r, g, b);
233
234 g_free (r);
235 g_free (g);
236 g_free (b);
237
238# else /* !HAVE_XF86VMODE_GAMMA_RAMP */
239 abort ();
240# endif /* !HAVE_XF86VMODE_GAMMA_RAMP */
241 }
242
243 display = cdk_display_get_default ();
244 cdk_display_flush (display);
245
246 return status;
247}
248
249#endif /* HAVE_XF86VMODE_GAMMA */
250
251/* VidModeExtension version 2.0 or better is needed to do gamma.
252 2.0 added gamma values; 2.1 added gamma ramps.
253*/
254# define XF86_VIDMODE_GAMMA_MIN_MAJOR2 2
255# define XF86_VIDMODE_GAMMA_MIN_MINOR0 0
256# define XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR2 2
257# define XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR1 1
258
259
260gboolean
261gs_fade_get_enabled (GSFade *fade)
262{
263 g_return_val_if_fail (GS_IS_FADE (fade), FALSE)do{ (void)0; }while (0);
264
265 return fade->priv->enabled;
266}
267
268void
269gs_fade_set_enabled (GSFade *fade,
270 gboolean enabled)
271{
272 g_return_if_fail (GS_IS_FADE (fade))do{ (void)0; }while (0);
273
274 if (fade->priv->enabled != enabled)
275 {
276 fade->priv->enabled = enabled;
277 }
278}
279
280#ifdef HAVE_XF86VMODE_GAMMA1
281static gboolean
282gamma_fade_setup (GSFade *fade)
283{
284 gboolean res;
285 struct GSFadeScreenPrivate *screen_priv;
286
287 screen_priv = &fade->priv->screen_priv;
288
289 if (screen_priv->info)
290 return TRUE(!(0));
291
292# ifndef HAVE_XF86VMODE_GAMMA_RAMP1
293 if (FADE_TYPE_GAMMA_RAMP == screen_priv->fade_type)
294 {
295 /* server is newer than client! */
296 screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
297 }
298# endif
299
300# ifdef HAVE_XF86VMODE_GAMMA_RAMP1
301
302 screen_priv->info = g_new0(struct GSGammaInfo, 1)((struct GSGammaInfo *) g_malloc0_n ((1), sizeof (struct GSGammaInfo
)))
;
303 screen_priv->num_ramps = 1;
304
305 if (FADE_TYPE_GAMMA_RAMP == screen_priv->fade_type)
306 {
307 /* have ramps */
308
309
310 res = XF86VidModeGetGammaRampSize (CDK_DISPLAY_XDISPLAY (cdk_display_get_default ())(cdk_x11_display_get_xdisplay (cdk_display_get_default ())),
311 CDK_SCREEN_XNUMBER (cdk_screen_get_default ())(cdk_x11_screen_get_screen_number (cdk_screen_get_default ())
)
,
312 &screen_priv->info->size);
313 if (!res || screen_priv->info->size <= 0)
314 {
315 screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
316 goto test_number;
317 }
318
319 screen_priv->info->r = g_new0 (unsigned short, screen_priv->info->size)((unsigned short *) g_malloc0_n ((screen_priv->info->size
), sizeof (unsigned short)))
;
320 screen_priv->info->g = g_new0 (unsigned short, screen_priv->info->size)((unsigned short *) g_malloc0_n ((screen_priv->info->size
), sizeof (unsigned short)))
;
321 screen_priv->info->b = g_new0 (unsigned short, screen_priv->info->size)((unsigned short *) g_malloc0_n ((screen_priv->info->size
), sizeof (unsigned short)))
;
322
323 if (! (screen_priv->info->r && screen_priv->info->g && screen_priv->info->b))
324 {
325 screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
326 goto test_number;
327 }
328
329 res = XF86VidModeGetGammaRamp (CDK_DISPLAY_XDISPLAY (cdk_display_get_default ())(cdk_x11_display_get_xdisplay (cdk_display_get_default ())),
330 CDK_SCREEN_XNUMBER (cdk_screen_get_default ())(cdk_x11_screen_get_screen_number (cdk_screen_get_default ())
)
,
331 screen_priv->info->size,
332 screen_priv->info->r,
333 screen_priv->info->g,
334 screen_priv->info->b);
335 if (! res)
336 {
337 screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
338 goto test_number;
339 }
340 gs_debug ("Initialized gamma ramp fade")gs_debug_real (__func__, "gs-fade.c", 340, "Initialized gamma ramp fade"
)
;
341 }
342# endif /* HAVE_XF86VMODE_GAMMA_RAMP */
343
344test_number:
345 if (FADE_TYPE_GAMMA_NUMBER == screen_priv->fade_type)
346 {
347 /* only have gamma parameter, not ramps. */
348
349 res = XF86VidModeGetGamma (CDK_DISPLAY_XDISPLAY (cdk_display_get_default ())(cdk_x11_display_get_xdisplay (cdk_display_get_default ())),
350 CDK_SCREEN_XNUMBER (cdk_screen_get_default ())(cdk_x11_screen_get_screen_number (cdk_screen_get_default ())
)
,
351 &screen_priv->vmg);
352 if (! res)
353 {
354 screen_priv->fade_type = FADE_TYPE_NONE;
355 goto test_none;
356 }
357 gs_debug ("Initialized gamma fade: %f %f %f",gs_debug_real (__func__, "gs-fade.c", 360, "Initialized gamma fade: %f %f %f"
, screen_priv->vmg.red, screen_priv->vmg.green, screen_priv
->vmg.blue)
358 screen_priv->vmg.red,gs_debug_real (__func__, "gs-fade.c", 360, "Initialized gamma fade: %f %f %f"
, screen_priv->vmg.red, screen_priv->vmg.green, screen_priv
->vmg.blue)
359 screen_priv->vmg.green,gs_debug_real (__func__, "gs-fade.c", 360, "Initialized gamma fade: %f %f %f"
, screen_priv->vmg.red, screen_priv->vmg.green, screen_priv
->vmg.blue)
360 screen_priv->vmg.blue)gs_debug_real (__func__, "gs-fade.c", 360, "Initialized gamma fade: %f %f %f"
, screen_priv->vmg.red, screen_priv->vmg.green, screen_priv
->vmg.blue)
;
361 }
362
363test_none:
364 if (FADE_TYPE_NONE == screen_priv->fade_type)
365 {
366 goto FAIL;
367 }
368
369 return TRUE(!(0));
370FAIL:
371
372 return FALSE(0);
373}
374#endif /* HAVE_XF86VMODE_GAMMA */
375
376static void
377screen_fade_finish (GSFade *fade)
378{
379 struct GSFadeScreenPrivate *screen_priv;
380 int i;
381 screen_priv = &fade->priv->screen_priv;
382
383 if (!screen_priv->info)
384 return;
385
386 for (i = 0; i < screen_priv->num_ramps; i++)
387 {
388 if (screen_priv->info[i].r)
389 g_free (screen_priv->info[i].r);
390 if (screen_priv->info[i].g)
391 g_free (screen_priv->info[i].g);
392 if (screen_priv->info[i].b)
393 g_free (screen_priv->info[i].b);
394 }
395
396 g_free (screen_priv->info);
397 screen_priv->info = NULL((void*)0);
398 screen_priv->num_ramps = 0;
399}
400
401#ifdef HAVE_XF86VMODE_GAMMA1
402static gboolean
403gamma_fade_set_alpha_gamma (GSFade *fade,
404 gdouble alpha)
405{
406 struct GSFadeScreenPrivate *screen_priv;
407 int screen_idx = CDK_SCREEN_XNUMBER (cdk_screen_get_default ())(cdk_x11_screen_get_screen_number (cdk_screen_get_default ())
)
;
408
409 screen_priv = &fade->priv->screen_priv;
410 xf86_whack_gamma (screen_idx, screen_priv, alpha);
411
412 return TRUE(!(0));
413}
414#endif /* HAVE_XF86VMODE_GAMMA */
415
416static void
417check_gamma_extension (GSFade *fade)
418{
419 struct GSFadeScreenPrivate *screen_priv;
420#ifdef HAVE_XF86VMODE_GAMMA1
421 int event;
422 int error;
423 int major;
424 int minor;
425 gboolean res;
426#endif /* HAVE_XF86VMODE_GAMMA */
427
428 screen_priv = &fade->priv->screen_priv;
429
430#ifdef HAVE_XF86VMODE_GAMMA1
431 res = XF86VidModeQueryExtension (CDK_DISPLAY_XDISPLAY (cdk_display_get_default ())(cdk_x11_display_get_xdisplay (cdk_display_get_default ())), &event, &error);
432 if (! res)
433 goto fade_none;
434
435 res = safe_XF86VidModeQueryVersion (CDK_DISPLAY_XDISPLAY (cdk_display_get_default ())(cdk_x11_display_get_xdisplay (cdk_display_get_default ())), &major, &minor);
436 if (! res)
437 goto fade_none;
438
439 if (major < XF86_VIDMODE_GAMMA_MIN_MAJOR2 ||
440 (major == XF86_VIDMODE_GAMMA_MIN_MAJOR2 &&
441 minor < XF86_VIDMODE_GAMMA_MIN_MINOR0))
442 goto fade_none;
443
444 screen_priv->fade_setup = gamma_fade_setup;
445 screen_priv->fade_finish = screen_fade_finish;
446 screen_priv->fade_set_alpha_gamma = gamma_fade_set_alpha_gamma;
447
448 if (major < XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR2 ||
449 (major == XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR2 &&
450 minor < XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR1))
451 {
452 screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
453 return;
454 }
455
456 /* Copacetic */
457 screen_priv->fade_type = FADE_TYPE_GAMMA_RAMP;
458 return;
459fade_none:
460#endif
461 screen_priv->fade_type = FADE_TYPE_NONE;
462}
463
464/* Xrandr support */
465
466static gboolean xrandr_fade_setup (GSFade *fade)
467{
468 struct GSFadeScreenPrivate *screen_priv;
469 CafeRRCrtc *crtc;
470 CafeRRCrtc **crtcs;
471 int crtc_count = 0;
472 struct GSGammaInfo *info;
473 gboolean res;
474
475 screen_priv = &fade->priv->screen_priv;
476
477 if (screen_priv->info)
1
Assuming field 'info' is null
2
Taking false branch
478 return TRUE(!(0));
479
480 /* refresh the screen info */
481 cafe_rr_screen_refresh (screen_priv->rrscreen, NULL((void*)0));
482
483 crtcs = cafe_rr_screen_list_crtcs (screen_priv->rrscreen);
484 while (*crtcs)
3
Loop condition is false. Execution continues on line 490
485 {
486 crtc_count++;
487 crtcs++;
488 };
489
490 screen_priv->info = g_new0 (struct GSGammaInfo, crtc_count)((struct GSGammaInfo *) g_malloc0_n ((crtc_count), sizeof (struct
GSGammaInfo)))
;
491 screen_priv->num_ramps = crtc_count;
492
493 crtc_count = 0;
494 crtcs = cafe_rr_screen_list_crtcs (screen_priv->rrscreen);
495 while (*crtcs)
4
Loop condition is true. Entering loop body
496 {
497 crtc = *crtcs;
498
499 info = &screen_priv->info[crtc_count];
500
501 /* if no mode ignore crtc */
502 if (!cafe_rr_crtc_get_current_mode (crtc))
5
Assuming the condition is false
6
Taking false branch
503 {
504 info->size = 0;
505 info->r = NULL((void*)0);
506 info->g = NULL((void*)0);
507 info->b = NULL((void*)0);
508 }
509 else
510 {
511 res = cafe_rr_crtc_get_gamma (crtc, &info->size,
7
Access of the heap area at index 0, while it holds only 0 'struct GSGammaInfo' element
512 &info->r, &info->g,
513 &info->b);
514 if (res == FALSE(0))
515 goto fail;
516 }
517
518 crtcs++;
519 crtc_count++;
520 }
521 return TRUE(!(0));
522fail:
523 return FALSE(0);
524}
525
526static void xrandr_crtc_whack_gamma (CafeRRCrtc *crtc,
527 struct GSGammaInfo *gamma_info,
528 float ratio)
529{
530 unsigned short *r, *g, *b;
531 int i;
532
533 if (gamma_info->size == 0)
534 return;
535
536 if (ratio < 0)
537 {
538 ratio = 0;
539 }
540 if (ratio > 1)
541 {
542 ratio = 1;
543 }
544
545 r = g_new0 (unsigned short, gamma_info->size)((unsigned short *) g_malloc0_n ((gamma_info->size), sizeof
(unsigned short)))
;
546 g = g_new0 (unsigned short, gamma_info->size)((unsigned short *) g_malloc0_n ((gamma_info->size), sizeof
(unsigned short)))
;
547 b = g_new0 (unsigned short, gamma_info->size)((unsigned short *) g_malloc0_n ((gamma_info->size), sizeof
(unsigned short)))
;
548
549 for (i = 0; i < gamma_info->size; i++)
550 {
551 r[i] = gamma_info->r[i] * ratio;
552 g[i] = gamma_info->g[i] * ratio;
553 b[i] = gamma_info->b[i] * ratio;
554 }
555
556 cafe_rr_crtc_set_gamma (crtc, gamma_info->size,
557 r, g, b);
558 g_free (r);
559 g_free (g);
560 g_free (b);
561}
562
563static gboolean xrandr_fade_set_alpha_gamma (GSFade *fade,
564 gdouble alpha)
565{
566 struct GSFadeScreenPrivate *screen_priv;
567 struct GSGammaInfo *info;
568 CafeRRCrtc **crtcs;
569 int i;
570
571 screen_priv = &fade->priv->screen_priv;
572
573 if (!screen_priv->info)
574 return FALSE(0);
575
576 crtcs = cafe_rr_screen_list_crtcs (screen_priv->rrscreen);
577 i = 0;
578
579 while (*crtcs)
580 {
581 info = &screen_priv->info[i];
582 xrandr_crtc_whack_gamma (*crtcs, info, alpha);
583 i++;
584 crtcs++;
585 }
586 return TRUE(!(0));
587}
588
589static void
590check_randr_extension (GSFade *fade)
591{
592 CdkDisplay *display = cdk_display_get_default ();
593 CdkScreen *screen = cdk_display_get_default_screen (display);
594 struct GSFadeScreenPrivate *screen_priv;
595
596 screen_priv = &fade->priv->screen_priv;
597
598 screen_priv->rrscreen = cafe_rr_screen_new (screen,
599 NULL((void*)0));
600 if (!screen_priv->rrscreen)
601 {
602 screen_priv->fade_type = FADE_TYPE_NONE;
603 return;
604 }
605
606 screen_priv->fade_type = FADE_TYPE_XRANDR;
607 screen_priv->fade_setup = xrandr_fade_setup;
608 screen_priv->fade_finish = screen_fade_finish;
609 screen_priv->fade_set_alpha_gamma = xrandr_fade_set_alpha_gamma;
610}
611
612static gboolean
613gs_fade_set_alpha (GSFade *fade,
614 gdouble alpha)
615{
616 gboolean ret = FALSE(0);
617
618 switch (fade->priv->screen_priv.fade_type)
619 {
620 case FADE_TYPE_GAMMA_RAMP:
621 case FADE_TYPE_GAMMA_NUMBER:
622 case FADE_TYPE_XRANDR:
623 ret = fade->priv->screen_priv.fade_set_alpha_gamma (fade, alpha);
624 break;
625 case FADE_TYPE_NONE:
626 ret = FALSE(0);
627 break;
628 default:
629 g_warning ("Unknown fade type");
630 ret = FALSE(0);
631 break;
632 }
633
634 return ret;
635}
636
637static gboolean
638gs_fade_out_iter (GSFade *fade)
639{
640 gboolean ret;
641
642 if (fade->priv->current_alpha < 0.01)
643 {
644 return FALSE(0);
645 }
646
647 fade->priv->current_alpha -= fade->priv->alpha_per_iter;
648
649 ret = gs_fade_set_alpha (fade, fade->priv->current_alpha);
650
651 return ret;
652}
653
654static gboolean
655gs_fade_stop (GSFade *fade)
656{
657 if (fade->priv->timer_id > 0)
658 {
659 g_source_remove (fade->priv->timer_id);
660 fade->priv->timer_id = 0;
661 }
662
663 fade->priv->step = 0;
664 fade->priv->active = FALSE(0);
665
666 return TRUE(!(0));
667}
668
669void
670gs_fade_finish (GSFade *fade)
671{
672 g_return_if_fail (GS_IS_FADE (fade))do{ (void)0; }while (0);
673
674 if (! fade->priv->active)
675 {
676 return;
677 }
678
679 gs_fade_stop (fade);
680
681 g_signal_emit (fade, signals [FADED], 0);
682
683 fade->priv->active = FALSE(0);
684}
685
686static gboolean
687fade_out_timer (GSFade *fade)
688{
689 gboolean res;
690
691 res = gs_fade_out_iter (fade);
692
693 /* if failed then fade is complete */
694 if (! res)
695 {
696 gs_fade_finish (fade);
697 return FALSE(0);
698 }
699
700 return TRUE(!(0));
701}
702
703gboolean
704gs_fade_get_active (GSFade *fade)
705{
706 g_return_val_if_fail (GS_IS_FADE (fade), FALSE)do{ (void)0; }while (0);
707
708 return fade->priv->active;
709}
710
711static void
712gs_fade_set_timeout (GSFade *fade,
713 guint timeout)
714{
715 g_return_if_fail (GS_IS_FADE (fade))do{ (void)0; }while (0);
716
717 fade->priv->timeout = timeout;
718}
719
720static void
721gs_fade_start (GSFade *fade,
722 guint timeout)
723{
724 guint steps_per_sec = 60;
725 guint msecs_per_step;
726 gboolean active_fade, res;
727
728 g_return_if_fail (GS_IS_FADE (fade))do{ (void)0; }while (0);
729
730 if (fade->priv->screen_priv.fade_type != FADE_TYPE_NONE)
731 {
732 res = fade->priv->screen_priv.fade_setup (fade);
733 if (res == FALSE(0))
734 return;
735 }
736
737 if (fade->priv->timer_id > 0)
738 {
739 gs_fade_stop (fade);
740 }
741
742 fade->priv->active = TRUE(!(0));
743
744 gs_fade_set_timeout (fade, timeout);
745
746 active_fade = FALSE(0);
747 if (fade->priv->screen_priv.fade_type != FADE_TYPE_NONE)
748 active_fade = TRUE(!(0));
749
750 if (active_fade)
751 {
752 guint num_steps;
753
754 num_steps = (fade->priv->timeout / 1000.0) * steps_per_sec;
755 msecs_per_step = 1000 / steps_per_sec;
756 fade->priv->alpha_per_iter = 1.0 / (gdouble)num_steps;
757
758 fade->priv->timer_id = g_timeout_add (msecs_per_step, (GSourceFunc)fade_out_timer, fade);
759 }
760 else
761 {
762 gs_fade_finish (fade);
763 }
764}
765
766typedef struct
767{
768 GSFadeDoneFunc done_cb;
769 gpointer data;
770} FadedCallbackData;
771
772static void
773gs_fade_async_callback (GSFade *fade,
774 FadedCallbackData *cdata)
775{
776 g_signal_handlers_disconnect_by_func (fade,g_signal_handlers_disconnect_matched ((fade), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (gs_fade_async_callback), (cdata))
777 gs_fade_async_callback,g_signal_handlers_disconnect_matched ((fade), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (gs_fade_async_callback), (cdata))
778 cdata)g_signal_handlers_disconnect_matched ((fade), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (gs_fade_async_callback), (cdata))
;
779
780 if (cdata->done_cb)
781 {
782 cdata->done_cb (fade, cdata->data);
783 }
784
785 g_free (cdata);
786}
787
788void
789gs_fade_async (GSFade *fade,
790 guint timeout,
791 GSFadeDoneFunc func,
792 gpointer data)
793{
794 g_return_if_fail (GS_IS_FADE (fade))do{ (void)0; }while (0);
795
796 /* if fade is active then pause it */
797 if (fade->priv->active)
798 {
799 gs_fade_stop (fade);
800 }
801
802 if (func)
803 {
804 FadedCallbackData *cb_data;
805
806 cb_data = g_new0 (FadedCallbackData, 1)((FadedCallbackData *) g_malloc0_n ((1), sizeof (FadedCallbackData
)))
;
807 cb_data->done_cb = func;
808 cb_data->data = data;
809
810 g_signal_connect (fade, "faded",g_signal_connect_data ((fade), ("faded"), (((GCallback) (gs_fade_async_callback
))), (cb_data), ((void*)0), (GConnectFlags) 0)
811 G_CALLBACK (gs_fade_async_callback),g_signal_connect_data ((fade), ("faded"), (((GCallback) (gs_fade_async_callback
))), (cb_data), ((void*)0), (GConnectFlags) 0)
812 cb_data)g_signal_connect_data ((fade), ("faded"), (((GCallback) (gs_fade_async_callback
))), (cb_data), ((void*)0), (GConnectFlags) 0)
;
813 }
814
815 gs_fade_start (fade, timeout);
816}
817
818static void
819gs_fade_sync_callback (GSFade *fade,
820 int *flag)
821{
822 *flag = TRUE(!(0));
823 g_signal_handlers_disconnect_by_func (fade,g_signal_handlers_disconnect_matched ((fade), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (gs_fade_sync_callback), (flag))
824 gs_fade_sync_callback,g_signal_handlers_disconnect_matched ((fade), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (gs_fade_sync_callback), (flag))
825 flag)g_signal_handlers_disconnect_matched ((fade), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (gs_fade_sync_callback), (flag))
;
826}
827
828void
829gs_fade_sync (GSFade *fade,
830 guint timeout)
831{
832 int flag = FALSE(0);
833
834 g_return_if_fail (GS_IS_FADE (fade))do{ (void)0; }while (0);
835
836 /* if fade is active then pause it */
837 if (fade->priv->active)
838 {
839 gs_fade_stop (fade);
840 }
841
842 g_signal_connect (fade, "faded",g_signal_connect_data ((fade), ("faded"), (((GCallback) (gs_fade_sync_callback
))), (&flag), ((void*)0), (GConnectFlags) 0)
843 G_CALLBACK (gs_fade_sync_callback),g_signal_connect_data ((fade), ("faded"), (((GCallback) (gs_fade_sync_callback
))), (&flag), ((void*)0), (GConnectFlags) 0)
844 &flag)g_signal_connect_data ((fade), ("faded"), (((GCallback) (gs_fade_sync_callback
))), (&flag), ((void*)0), (GConnectFlags) 0)
;
845
846 gs_fade_start (fade, timeout);
847
848 while (! flag)
849 {
850 ctk_main_iteration ();
851 }
852}
853
854void
855gs_fade_reset (GSFade *fade)
856{
857 g_return_if_fail (GS_IS_FADE (fade))do{ (void)0; }while (0);
858
859 gs_debug ("Resetting fade")gs_debug_real (__func__, "gs-fade.c", 859, "Resetting fade");
860
861 if (fade->priv->active)
862 {
863 gs_fade_stop (fade);
864 }
865
866 fade->priv->current_alpha = 1.0;
867
868 gs_fade_set_alpha (fade, fade->priv->current_alpha);
869
870 if (fade->priv->screen_priv.fade_type != FADE_TYPE_NONE)
871 fade->priv->screen_priv.fade_finish (fade);
872}
873
874static void
875gs_fade_class_init (GSFadeClass *klass)
876{
877 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
878
879 object_class->finalize = gs_fade_finalize;
880
881 signals [FADED] =
882 g_signal_new ("faded",
883 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
884 G_SIGNAL_RUN_LAST,
885 G_STRUCT_OFFSET (GSFadeClass, faded)((glong) __builtin_offsetof(GSFadeClass, faded)),
886 NULL((void*)0),
887 NULL((void*)0),
888 g_cclosure_marshal_VOID__VOID,
889 G_TYPE_NONE((GType) ((1) << (2))),
890 0, G_TYPE_NONE((GType) ((1) << (2))));
891}
892
893static void
894gs_fade_init (GSFade *fade)
895{
896 fade->priv = gs_fade_get_instance_private (fade);
897
898 fade->priv->timeout = 1000;
899 fade->priv->current_alpha = 1.0;
900
901 check_randr_extension (fade);
902 if (!fade->priv->screen_priv.fade_type)
903 check_gamma_extension (fade);
904 gs_debug ("Fade type: %d", fade->priv->screen_priv.fade_type)gs_debug_real (__func__, "gs-fade.c", 904, "Fade type: %d", fade
->priv->screen_priv.fade_type)
;
905}
906
907static void
908gs_fade_finalize (GObject *object)
909{
910 GSFade *fade;
911
912 g_return_if_fail (object != NULL)do{ (void)0; }while (0);
913 g_return_if_fail (GS_IS_FADE (object))do{ (void)0; }while (0);
914
915 fade = GS_FADE (object)((((GSFade*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((gs_fade_get_type ()))))))
;
916
917 g_return_if_fail (fade->priv != NULL)do{ (void)0; }while (0);
918
919 fade->priv->screen_priv.fade_finish(fade);
920
921 if (fade->priv->screen_priv.rrscreen)
922 g_object_unref (fade->priv->screen_priv.rrscreen);
923 fade->priv->screen_priv.rrscreen = NULL((void*)0);
924
925 G_OBJECT_CLASS (gs_fade_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gs_fade_parent_class)), (((GType) ((20) << (2)))))
)))
->finalize (object);
926}
927
928GSFade *
929gs_fade_new (void)
930{
931 if (fade_object)
932 {
933 g_object_ref (fade_object)((__typeof__ (fade_object)) (g_object_ref) (fade_object));
934 }
935 else
936 {
937 fade_object = g_object_new (GS_TYPE_FADE(gs_fade_get_type ()), NULL((void*)0));
938 g_object_add_weak_pointer (fade_object,
939 (gpointer *) &fade_object);
940 }
941
942 return GS_FADE (fade_object)((((GSFade*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fade_object)), ((gs_fade_get_type ()))))))
;
943}