From a50faed99ac4c096df0a729d88de78f376de7f64 Mon Sep 17 00:00:00 2001 From: "raveit65 (via Travis CI)" Date: Wed, 21 Feb 2024 23:51:38 +0000 Subject: Deploy mate-desktop/mate-screensaver to github.com/mate-desktop/mate-screensaver.git:gh-pages --- .../0.html | 595 +++ .../1.html | 815 +++ .../10.html | 1361 +++++ .../11.html | 5313 +++++++++++++++++++ .../12.html | 5021 ++++++++++++++++++ .../13.html | 4171 +++++++++++++++ .../14.html | 1141 ++++ .../15.html | 1587 ++++++ .../16.html | 5425 ++++++++++++++++++++ .../17.html | 1349 +++++ .../18.html | 977 ++++ .../19.html | 3891 ++++++++++++++ .../2.html | 2651 ++++++++++ .../20.html | 507 ++ .../3.html | 1443 ++++++ .../4.html | 2335 +++++++++ .../5.html | 1257 +++++ .../6.html | 445 ++ .../7.html | 1857 +++++++ .../8.html | 577 +++ .../9.html | 2105 ++++++++ .../index.html | 297 ++ .../stats.html | 190 + .../style.css | 177 + 24 files changed, 45487 insertions(+) create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/0.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/1.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/10.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/11.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/12.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/13.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/14.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/15.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/16.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/17.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/18.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/19.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/2.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/20.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/3.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/4.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/5.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/6.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/7.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/8.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/9.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/index.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/stats.html create mode 100644 2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/style.css (limited to '2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729') diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/0.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/0.html new file mode 100644 index 0000000..56df6aa --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/0.html @@ -0,0 +1,595 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
/* Part of mate-screensaver.
+ *
+ * Copyright (c) 2019-2021 Paul Wolneykien <manowar@altlinux.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* Provides functions for two-way communication between the screensaver
+ * and the helper program. The idea of helper program is to be able to
+ * run mate-screensaver-dialog without any setuid bits.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "helper_proto.h"
+
+static ssize_t
+read_all (int fd, void *buf, size_t count)
+{
+    ssize_t rd, t_rd = 0;
+
+    if (0 == count)
+        return 0;
+
+    while (t_rd < count)
+    {
+        rd = read (fd, buf + t_rd, count - t_rd);
+        if (0 == rd)
+            break;
+        if (rd < 0)
+            return rd;
+        t_rd += rd;
+    }
+
+    return t_rd;
+}
+
+ssize_t
+read_msg (int fd, char *buf, size_t length)
+{
+    size_t msg_len;
+    ssize_t rd;
+
+    rd = read_all (fd, &msg_len, sizeof msg_len);
+    if (rd < 0)
+        return HELPER_IO_ERR;
+    if (rd > 0 && rd != sizeof msg_len)
+        return HELPER_LENGTH_READ_ERR;
+
+    if (msg_len >= length)
+        return HELPER_TOO_LONG_ERR;
+
+    if (msg_len > 0)
+    {
+        rd = read_all (fd, buf, msg_len);
+        if (rd < 0)
+            return HELPER_IO_ERR;
+        if (rd != msg_len)
+            return HELPER_MSG_READ_ERR;
+    }
+    else
+        rd = 0;
+    buf[rd] = '\0';
+
+    return rd;
+}
+
+int
+read_prompt (int fd, char *buf, size_t *length)
+{
+    int msg_type, rd;
+
+    rd = read_all (fd, &msg_type, sizeof msg_type);
+    if (0 == rd)<--- Assuming that condition '0==rd' is not redundant
+        return 0;
+    if (rd < 0)<--- Assuming condition is false
+        return HELPER_IO_ERR;
+    if (rd > 0 && rd != sizeof msg_type)<--- Condition 'rd>0' is always true
+        return HELPER_TYPE_READ_ERR;
+
+    rd = read_msg (fd, buf, *length);
+    if (rd < 0)
+        return rd;
+
+    *length = rd;
+    return msg_type;
+}
+
+static ssize_t
+write_all (int fd, const void *buf, size_t count)
+{
+    ssize_t wt, t_wt = 0;
+
+    if (0 == count)
+        return 0;
+
+    while (t_wt < count)
+    {
+        wt = write (fd, buf + t_wt, count - t_wt);
+        if (0 == wt)
+            break;
+        if (wt < 0)
+            return wt;
+        t_wt += wt;
+    }
+
+    return t_wt;
+}
+
+ssize_t
+write_msg (int fd, const void *buf, size_t length)
+{
+    ssize_t wt;
+
+    wt = write_all (fd, &length, sizeof length);
+    if (wt < 0)
+        return HELPER_IO_ERR;
+    if (wt > 0 && wt != sizeof length)
+        return HELPER_LENGTH_WRITE_ERR;
+
+    if (length > 0)
+    {
+        wt = write_all (fd, buf, length);
+        if (wt < 0)
+            return HELPER_IO_ERR;
+        if (wt != length)
+            return HELPER_MSG_WRITE_ERR;
+    }
+    else
+        wt = 0;
+
+    return wt;
+}
+
+int
+write_prompt (int fd, int msg_type, const void *buf, size_t length)
+{
+    ssize_t wt;
+
+    wt = write_all (fd, &msg_type, sizeof msg_type);
+    if (wt < 0)
+        return HELPER_IO_ERR;
+    if (wt > 0 && wt != sizeof msg_type)
+        return HELPER_TYPE_WRITE_ERR;
+
+    wt = write_msg (fd, buf, length);
+
+    return wt;
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/1.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/1.html new file mode 100644 index 0000000..f72d9a1 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/1.html @@ -0,0 +1,815 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
/* Part of mate-screensaver.
+ *
+ * Copyright (C) 2002 SuSE Linux AG.
+ * Copyright (c) 2019-2021 Paul Wolneykien <manowar@altlinux.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/*
+ * Set*id helper program for PAM authentication.
+ *
+ * It is supposed to be called from mate-screensaver
+ * in order to communicate with Linux PAM as a privileged proxy.
+ * The conversation messages from the PAM stack is transmitted to
+ * mate-screensaver dialog via stdout and the received user replies
+ * read from stdin are sent back to PAM.
+ *
+ * Based on the helper written by okir@suse.de, loosely based on
+ * unix_chkpwd by Andrew Morgan.
+ */
+
+#include <security/pam_appl.h>
+#include <security/_pam_macros.h>
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <limits.h>
+
+#include "helper_proto.h"
+#include "gs-auth-pam.h"
+
+#define MAXLEN 1024
+
+enum {
+    UNIX_PASSED = 0,
+    UNIX_FAILED = 1
+};
+
+static char * program_name;<--- Shadowed declaration
+
+/*
+ * Log error messages
+ */
+static void
+_log_err(int err, const char *format,...)
+{
+    va_list args;
+
+    va_start(args, format);
+    openlog(program_name, LOG_CONS | LOG_PID, LOG_AUTH);
+    vsyslog(err, format, args);
+    va_end(args);
+    closelog();
+}
+
+static void
+su_sighandler(int sig)
+{
+    if (sig > 0) {
+        _log_err(LOG_NOTICE, "caught signal %d.", sig);
+        exit(sig);
+    }
+}
+
+/*
+ * Setup signal handlers
+ */
+static void
+setup_signals(void)
+{
+    struct sigaction action;
+
+    memset((void *) &action, 0, sizeof(action));
+    action.sa_handler = su_sighandler;
+    action.sa_flags = SA_RESETHAND;
+    sigaction(SIGILL, &action, NULL);
+    sigaction(SIGTRAP, &action, NULL);
+    sigaction(SIGBUS, &action, NULL);
+    sigaction(SIGSEGV, &action, NULL);
+    action.sa_handler = SIG_IGN;
+    action.sa_flags = 0;
+    sigaction(SIGTERM, &action, NULL);
+    sigaction(SIGHUP, &action, NULL);
+    sigaction(SIGINT, &action, NULL);
+    sigaction(SIGQUIT, &action, NULL);
+    sigaction(SIGALRM, &action, NULL);
+}
+
+static int
+_converse(int num_msg, const struct pam_message **msg,
+          struct pam_response **resp, void *appdata_ptr)
+{
+    struct pam_response *reply = NULL;
+    char buf[MAXLEN];
+    int num;
+    int ret = PAM_SUCCESS;
+
+    if (!(reply = malloc(sizeof(*reply) * num_msg)))
+        return PAM_CONV_ERR;
+
+    for (num = 0; num < num_msg; num++) {
+        ssize_t wt, rd;
+        size_t msg_len = strlen(msg[num]->msg);
+        wt = write_prompt (STDOUT_FILENO,
+                   pam_style_to_gs_style (msg[num]->msg_style),
+                   msg[num]->msg, msg_len);
+        if (wt < 0 || wt != msg_len) {
+            _log_err(LOG_ERR, "error writing promt");
+            ret = PAM_CONV_ERR;
+            break;
+        }
+
+        rd = read_msg (STDIN_FILENO, buf, sizeof (buf));
+        if (rd < 0) {
+            _log_err(LOG_ERR, "error reading reply");
+            ret = PAM_CONV_ERR;
+            break;
+        }
+
+        reply[num].resp = malloc (rd + 1);
+        if (!reply[num].resp)
+            ret = PAM_BUF_ERR;
+        else {
+            reply[num].resp_retcode = 0;
+            memcpy (reply[num].resp, buf, rd);
+            reply[num].resp[rd] = '\0';
+        }
+    }
+
+    if (ret != PAM_SUCCESS && reply != NULL) {
+        for (num = 0; num < num_msg; num++)
+            free (reply[num].resp);
+        free (reply);
+        *resp = NULL;
+    } else
+        *resp = reply;
+
+    return ret;
+}
+
+static int
+_authenticate(const char *service, const char *user)
+{
+    struct pam_conv conv = { _converse, NULL };
+    pam_handle_t *pamh;
+    int err;
+
+    err = pam_start(service, user, &conv, &pamh);
+    if (err != PAM_SUCCESS) {
+        _log_err(LOG_ERR, "pam_start(%s, %s) failed (errno %d)",
+                service, user, err);
+        return UNIX_FAILED;
+    }
+
+    err = pam_authenticate(pamh, 0);
+    if (err != PAM_SUCCESS)
+        _log_err(LOG_ERR, "pam_authenticate(%s, %s): %s",
+                service, user,
+                pam_strerror(pamh, err));
+
+    if (err == PAM_SUCCESS)
+    {
+        int err2 = pam_setcred(pamh, PAM_REFRESH_CRED);
+        if (err2 != PAM_SUCCESS)
+            _log_err(LOG_ERR, "pam_setcred(%s, %s): %s",
+                     service, user,
+                     pam_strerror(pamh, err2));
+        /*
+         * ignore errors on refresh credentials.
+         * If this did not work we use the old once.
+         */
+    }
+
+    pam_end(pamh, err);
+
+    if (err != PAM_SUCCESS)
+        return UNIX_FAILED;
+    return UNIX_PASSED;
+}
+
+static char *
+getuidname(uid_t uid)
+{
+    struct passwd *pw;
+    static char username[32];
+
+    pw = getpwuid(uid);
+    if (pw == NULL)
+        return NULL;
+
+    strncpy(username, pw->pw_name, sizeof(username));
+    username[sizeof(username) - 1] = '\0';
+
+    endpwent();
+    return username;
+}
+
+int
+main(int argc, char *argv[])
+{
+    const char *program_name;<--- Shadow variable
+    char *service, *user;
+    int fd;
+    uid_t uid;
+
+    uid = getuid();
+
+    /*
+     * Make sure standard file descriptors are connected.
+     */
+    while ((fd = open("/dev/null", O_RDWR)) <= 2)
+        ;
+    close(fd);
+
+    /*
+     * Get the program name
+     */
+    if ((program_name = strrchr(argv[0], '/')) != NULL)
+        program_name++;<--- Variable 'program_name' is assigned a value that is never used.
+    else
+        program_name = argv[0];<--- Variable 'program_name' is assigned a value that is never used.
+
+    /*
+     * Catch or ignore as many signal as possible.
+     */
+    setup_signals();
+
+    /*
+     * Check argument list
+     */
+    if (argc < 2 || argc > 3) {
+        _log_err(LOG_NOTICE, "Bad number of arguments (%d)", argc);
+        return UNIX_FAILED;
+    }
+
+    /*
+     * Get the service name.
+     */
+    service = argv[1];
+
+    /*
+     * Discourage users messing around (fat chance)
+     */
+    if (isatty(STDIN_FILENO) && uid != 0) {
+        _log_err(LOG_NOTICE,
+            "Inappropriate use of Unix helper binary [UID=%d]",
+             uid);
+        fprintf(stderr,
+            "This binary is not designed for running in this way\n"
+            "-- the system administrator has been informed\n");
+        sleep(10); /* this should discourage/annoy the user */
+        return UNIX_FAILED;
+    }
+
+    /*
+     * determine the caller's user name
+     */
+    user = getuidname(uid);
+    if (argc == 3 && strcmp(user, argv[2])) {
+        user = argv[2];
+        /* Discourage use of this program as a
+         * password cracker */
+        if (uid != 0)
+            sleep(5);
+    }
+    return _authenticate(service, user);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/10.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/10.html new file mode 100644 index 0000000..e1c2f39 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/10.html @@ -0,0 +1,1361 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
+
+#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
+#include <sys/resource.h>
+#endif
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include "gs-debug.h"
+#include "gs-job.h"
+
+#include "subprocs.h"
+
+static void gs_job_finalize   (GObject    *object);
+
+typedef enum
+{
+    GS_JOB_INVALID,
+    GS_JOB_RUNNING,
+    GS_JOB_STOPPED,
+    GS_JOB_KILLED,
+    GS_JOB_DEAD
+} GSJobStatus;
+
+struct GSJobPrivate
+{
+	GtkWidget      *widget;
+
+	GSJobStatus     status;
+	gint            pid;
+	guint           watch_id;
+
+	char           *command;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSJob, gs_job, G_TYPE_OBJECT)
+
+static char *
+widget_get_id_string (GtkWidget *widget)
+{
+	char *id = NULL;
+
+	g_return_val_if_fail (widget != NULL, NULL);
+
+	id = g_strdup_printf ("0x%X",
+	                      (guint32)GDK_WINDOW_XID (gtk_widget_get_window (widget)));
+	return id;
+}
+
+static void
+gs_job_class_init (GSJobClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize  = gs_job_finalize;
+}
+
+static void
+gs_job_init (GSJob *job)
+{
+	job->priv = gs_job_get_instance_private (job);
+}
+
+/* adapted from gspawn.c */
+static int
+wait_on_child (int pid)
+{
+	int status;
+
+wait_again:
+	if (waitpid (pid, &status, 0) < 0)
+	{
+		if (errno == EINTR)
+		{
+			goto wait_again;
+		}
+		else if (errno == ECHILD)
+		{
+			; /* do nothing, child already reaped */
+		}
+		else
+		{
+			gs_debug ("waitpid () should not fail in 'GSJob'");
+		}
+	}
+
+	return status;
+}
+
+static void
+gs_job_died (GSJob *job)
+{
+	if (job->priv->pid > 0)
+	{
+		int exit_status;
+
+		gs_debug ("Waiting on process %d", job->priv->pid);
+		exit_status = wait_on_child (job->priv->pid);
+
+		job->priv->status = GS_JOB_DEAD;
+
+		if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0))
+		{
+			gs_debug ("Wait on child process failed");
+		}
+		else
+		{
+			/* exited normally */
+		}
+	}
+	g_spawn_close_pid (job->priv->pid);
+	job->priv->pid = 0;
+
+	gs_debug ("Job died");
+}
+
+static void
+gs_job_finalize (GObject *object)
+{
+	GSJob *job;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GS_IS_JOB (object));
+
+	job = GS_JOB (object);
+
+	g_return_if_fail (job->priv != NULL);
+
+	if (job->priv->pid > 0)
+	{
+		signal_pid (job->priv->pid, SIGTERM);
+		gs_job_died (job);
+	}
+
+	g_free (job->priv->command);
+	job->priv->command = NULL;
+
+	G_OBJECT_CLASS (gs_job_parent_class)->finalize (object);
+}
+
+void
+gs_job_set_widget  (GSJob     *job,
+                    GtkWidget *widget)
+{
+	g_return_if_fail (job != NULL);
+	g_return_if_fail (GS_IS_JOB (job));
+
+	if (widget != job->priv->widget)
+	{
+		job->priv->widget = widget;
+
+		/* restart job */
+		if (gs_job_is_running (job))
+		{
+			gs_job_stop (job);
+			gs_job_start (job);
+		}
+	}
+}
+
+gboolean
+gs_job_set_command  (GSJob      *job,
+                     const char *command)
+{
+	g_return_val_if_fail (GS_IS_JOB (job), FALSE);
+
+	gs_debug ("Setting command for job: '%s'",
+	          command != NULL ? command : "NULL");
+
+	g_free (job->priv->command);
+	job->priv->command = g_strdup (command);
+
+	return TRUE;
+}
+
+GSJob *
+gs_job_new (void)
+{
+	GObject *job;
+
+	job = g_object_new (GS_TYPE_JOB, NULL);
+
+	return GS_JOB (job);
+}
+
+GSJob *
+gs_job_new_for_widget (GtkWidget  *widget)
+{
+	GObject *job;
+
+	job = g_object_new (GS_TYPE_JOB, NULL);
+
+	gs_job_set_widget (GS_JOB (job), widget);
+
+	return GS_JOB (job);
+}
+
+static void
+nice_process (int pid,
+              int nice_level)
+{
+	g_return_if_fail (pid > 0);
+
+	if (nice_level == 0)
+	{
+		return;
+	}
+
+#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
+	gs_debug ("Setting child process priority to: %d", nice_level);
+	if (setpriority (PRIO_PROCESS, pid, nice_level) != 0)<--- Skipping configuration 'HAVE_SETPRIORITY;PRIO_PROCESS' since the value of 'PRIO_PROCESS' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly.
+	{
+		gs_debug ("setpriority(PRIO_PROCESS, %lu, %d) failed",
+		          (unsigned long) pid, nice_level);
+	}
+#else
+	gs_debug ("don't know how to change process priority on this system.");
+#endif
+}
+
+static GPtrArray *
+get_env_vars (GtkWidget *widget)
+{
+	GPtrArray   *env;
+	const gchar *display_name;
+	gchar       *str;
+	int          i;
+	static const char *allowed_env_vars [] =
+	{
+		"PATH",
+		"SESSION_MANAGER",
+		"XAUTHORITY",
+		"XAUTHLOCALHOSTNAME",
+		"LANG",
+		"LANGUAGE",
+		"DBUS_SESSION_BUS_ADDRESS"
+	};
+
+	env = g_ptr_array_new ();
+
+	display_name = gdk_display_get_name (gtk_widget_get_display (widget));
+	g_ptr_array_add (env, g_strdup_printf ("DISPLAY=%s", display_name));
+
+	g_ptr_array_add (env, g_strdup_printf ("HOME=%s",
+	                                       g_get_home_dir ()));
+
+	for (i = 0; i < G_N_ELEMENTS (allowed_env_vars); i++)
+	{
+		const char *var;
+		const char *val;
+		var = allowed_env_vars [i];
+		val = g_getenv (var);
+		if (val != NULL)
+		{
+			g_ptr_array_add (env, g_strdup_printf ("%s=%s",
+			                                       var,
+			                                       val));
+		}
+	}
+
+	str = widget_get_id_string (widget);
+	g_ptr_array_add (env, g_strdup_printf ("XSCREENSAVER_WINDOW=%s", str));
+	g_free (str);
+
+	g_ptr_array_add (env, NULL);
+
+	return env;
+}
+
+static gboolean
+spawn_on_widget (GtkWidget  *widget,
+                 const char *command,
+                 int        *pid,
+                 GIOFunc     watch_func,
+                 gpointer    user_data,
+                 guint      *watch_id)
+{
+	char      **argv;
+	GPtrArray  *env;
+	gboolean    result;
+	GIOChannel *channel;
+	GError     *error = NULL;
+	int         standard_error;
+	int         child_pid;
+	int         id;
+	int         i;
+
+	if (command == NULL)
+	{
+		return FALSE;
+	}
+
+	if (! g_shell_parse_argv (command, NULL, &argv, &error))
+	{
+		gs_debug ("Could not parse command: %s", error->message);
+		g_error_free (error);
+		return FALSE;
+	}
+
+	env = get_env_vars (widget);
+
+	error = NULL;
+	result = g_spawn_async_with_pipes (NULL,
+	         argv,
+	         (char **)env->pdata,
+	         G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+	         NULL,
+	         NULL,
+	         &child_pid,
+	         NULL,
+	         NULL,
+	         &standard_error,
+	         &error);
+
+	for (i = 0; i < env->len; i++)
+	{
+		g_free (g_ptr_array_index (env, i));
+	}
+	g_ptr_array_free (env, TRUE);
+
+	if (! result)
+	{
+		gs_debug ("Could not start command '%s': %s", command, error->message);
+		g_error_free (error);
+		g_strfreev (argv);
+		return FALSE;
+	}
+
+	g_strfreev (argv);
+
+	nice_process (child_pid, 10);
+
+	if (pid != NULL)
+	{
+		*pid = child_pid;
+	}
+	else
+	{
+		g_spawn_close_pid (child_pid);
+	}
+
+	channel = g_io_channel_unix_new (standard_error);
+	g_io_channel_set_close_on_unref (channel, TRUE);
+	g_io_channel_set_flags (channel,
+	                        g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK,
+	                        NULL);
+	id = g_io_add_watch (channel,
+	                     G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+	                     watch_func,
+	                     user_data);
+	if (watch_id != NULL)
+	{
+		*watch_id = id;
+	}
+
+	g_io_channel_unref (channel);
+
+	return result;
+}
+
+static gboolean
+command_watch (GIOChannel   *source,
+               GIOCondition  condition,
+               GSJob        *job)
+{
+	GIOStatus status;
+	GError   *error = NULL;
+	gboolean  done  = FALSE;
+
+	g_return_val_if_fail (job != NULL, FALSE);
+
+	if (condition & G_IO_IN)
+	{
+		char *str;
+
+		status = g_io_channel_read_line (source, &str, NULL, NULL, &error);
+
+		if (status == G_IO_STATUS_NORMAL)
+		{
+			gs_debug ("command output: %s", str);
+
+		}
+		else if (status == G_IO_STATUS_EOF)
+		{
+			done = TRUE;
+
+		}
+		else if (error != NULL)
+		{
+			gs_debug ("command error: %s", error->message);
+			g_error_free (error);
+		}
+
+		g_free (str);
+	}
+	else if (condition & G_IO_HUP)
+	{
+		done = TRUE;
+	}
+
+	if (done)
+	{
+		gs_job_died (job);
+
+		job->priv->watch_id = 0;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+gboolean
+gs_job_is_running (GSJob *job)
+{
+	gboolean running;
+
+	g_return_val_if_fail (GS_IS_JOB (job), FALSE);
+
+	running = (job->priv->pid > 0);
+
+	return running;
+}
+
+gboolean
+gs_job_start (GSJob *job)
+{
+	gboolean result;
+
+	g_return_val_if_fail (job != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_JOB (job), FALSE);
+
+	gs_debug ("starting job");
+
+	if (job->priv->pid != 0)
+	{
+		gs_debug ("Cannot restart active job.");
+		return FALSE;
+	}
+
+	if (job->priv->widget == NULL)
+	{
+		gs_debug ("Could not start job: screensaver window is not set.");
+		return FALSE;
+	}
+
+	if (job->priv->command == NULL)
+	{
+		/* no warning here because a NULL command is interpreted
+		   as a no-op job */
+		gs_debug ("No command set for job.");
+		return FALSE;
+	}
+
+	result = spawn_on_widget (job->priv->widget,
+	                          job->priv->command,
+	                          &job->priv->pid,
+	                          (GIOFunc)command_watch,
+	                          job,
+	                          &job->priv->watch_id);
+
+	if (result)
+	{
+		job->priv->status = GS_JOB_RUNNING;
+	}
+
+	return result;
+}
+
+static void
+remove_command_watch (GSJob *job)
+{
+	if (job->priv->watch_id != 0)
+	{
+		g_source_remove (job->priv->watch_id);
+		job->priv->watch_id = 0;
+	}
+}
+
+gboolean
+gs_job_stop (GSJob *job)
+{
+	g_return_val_if_fail (job != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_JOB (job), FALSE);
+
+	gs_debug ("stopping job");
+
+	if (job->priv->pid == 0)
+	{
+		gs_debug ("Could not stop job: pid not defined");
+		return FALSE;
+	}
+
+	if (job->priv->status == GS_JOB_STOPPED)
+	{
+		gs_job_suspend (job, FALSE);
+	}
+
+	remove_command_watch (job);
+
+	signal_pid (job->priv->pid, SIGTERM);
+
+	job->priv->status = GS_JOB_KILLED;
+
+	gs_job_died (job);
+
+	return TRUE;
+}
+
+gboolean
+gs_job_suspend (GSJob   *job,
+                gboolean suspend)
+{
+	g_return_val_if_fail (job != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_JOB (job), FALSE);
+
+	gs_debug ("suspending job");
+
+	if (job->priv->pid == 0)
+	{
+		return FALSE;
+	}
+
+	signal_pid (job->priv->pid, (suspend ? SIGSTOP : SIGCONT));
+
+	job->priv->status = (suspend ? GS_JOB_STOPPED : GS_JOB_RUNNING);
+
+	return TRUE;
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/11.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/11.html new file mode 100644 index 0000000..9f6062c --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/11.html @@ -0,0 +1,5313 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib/gi18n.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#ifdef WITH_SYSTEMD
+#include <systemd/sd-login.h>
+#endif
+
+#include "gs-listener-dbus.h"
+#include "gs-marshal.h"
+#include "gs-debug.h"
+
+static void              gs_listener_finalize           (GObject         *object);
+
+static void              gs_listener_unregister_handler (DBusConnection  *connection,
+        void            *data);
+
+static DBusHandlerResult gs_listener_message_handler    (DBusConnection  *connection,
+        DBusMessage     *message,
+        void            *user_data);
+
+#define GS_LISTENER_SERVICE   "org.mate.ScreenSaver"
+#define GS_LISTENER_PATH      "/org/mate/ScreenSaver"
+#define GS_LISTENER_INTERFACE "org.mate.ScreenSaver"
+
+/* systemd logind */
+#define SYSTEMD_LOGIND_SERVICE   "org.freedesktop.login1"
+#define SYSTEMD_LOGIND_PATH      "/org/freedesktop/login1"
+#define SYSTEMD_LOGIND_INTERFACE "org.freedesktop.login1.Manager"
+
+#define SYSTEMD_LOGIND_SESSION_INTERFACE "org.freedesktop.login1.Session"
+#define SYSTEMD_LOGIND_SESSION_PATH      "/org/freedesktop/login1/session"
+
+/* consolekit */
+#define CK_NAME              "org.freedesktop.ConsoleKit"
+#define CK_MANAGER_PATH      "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
+
+#define SESSION_NAME         "org.gnome.SessionManager"
+#define SESSION_PATH         "/org/gnome/SessionManager"
+#define SESSION_INTERFACE    "org.gnome.SessionManager"
+
+#define TYPE_MISMATCH_ERROR GS_LISTENER_INTERFACE ".TypeMismatch"
+
+struct GSListenerPrivate
+{
+	DBusConnection *connection;
+	DBusConnection *system_connection;
+
+	guint           session_idle : 1;
+	guint           active : 1;
+	guint           activation_enabled : 1;
+	guint           throttled : 1;
+	GHashTable     *inhibitors;
+	GHashTable     *throttlers;
+	time_t          active_start;
+	time_t          session_idle_start;
+	char           *session_id;
+
+#ifdef WITH_SYSTEMD
+	gboolean        have_systemd;
+	gint            logind_inhibit_lock;
+#endif
+
+	guint32         ck_throttle_cookie;
+};
+
+typedef struct
+{
+	int      entry_type;
+	char    *application;
+	char    *reason;
+	char    *connection;
+	guint32  cookie;
+	guint32  foreign_cookie;
+	gint64   since;
+} GSListenerRefEntry;
+
+enum
+{
+    LOCK,
+    CYCLE,
+    QUIT,
+    SIMULATE_USER_ACTIVITY,
+    ACTIVE_CHANGED,
+    THROTTLE_CHANGED,
+    SHOW_MESSAGE,
+    PREPARE_FOR_SLEEP,
+    LAST_SIGNAL,
+};
+
+enum
+{
+    PROP_0,
+    PROP_ACTIVE,
+    PROP_SESSION_IDLE,
+    PROP_ACTIVATION_ENABLED,
+};
+
+enum
+{
+    REF_ENTRY_TYPE_INHIBIT,
+    REF_ENTRY_TYPE_THROTTLE
+};
+
+static DBusObjectPathVTable
+gs_listener_vtable = { &gs_listener_unregister_handler,
+                       &gs_listener_message_handler,
+                       NULL,
+                       NULL,
+                       NULL,
+                       NULL
+                     };
+
+static guint         signals [LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSListener, gs_listener, G_TYPE_OBJECT)<--- There is an unknown macro here somewhere. Configuration is required. If G_DEFINE_TYPE_WITH_PRIVATE is a macro then please configure it.
+
+GQuark
+gs_listener_error_quark (void)
+{
+	static GQuark quark = 0;
+	if (!quark)
+	{
+		quark = g_quark_from_static_string ("gs_listener_error");
+	}
+
+	return quark;
+}
+
+static void
+gs_listener_ref_entry_free (GSListenerRefEntry *entry)
+{
+	g_free (entry->connection);
+	g_free (entry->application);
+	g_free (entry->reason);
+	g_free (entry);
+	entry = NULL;
+}
+
+static void
+gs_listener_unregister_handler (DBusConnection *connection,
+                                void           *data)
+{
+}
+
+static gboolean
+send_dbus_message (DBusConnection *connection,
+                   DBusMessage    *message)
+{
+	gboolean is_connected;
+	gboolean sent;
+
+	g_return_val_if_fail (message != NULL, FALSE);
+
+	if (! connection)
+	{
+		gs_debug ("There is no valid connection to the message bus");
+		return FALSE;
+	}
+
+	is_connected = dbus_connection_get_is_connected (connection);
+	if (! is_connected)
+	{
+		gs_debug ("Not connected to the message bus");
+		return FALSE;
+	}
+
+	sent = dbus_connection_send (connection, message, NULL);
+
+	return sent;
+}
+
+static void
+send_dbus_boolean_signal (GSListener *listener,
+                          const char *name,
+                          gboolean    value)
+{
+	DBusMessage    *message;
+	DBusMessageIter iter;
+
+	g_return_if_fail (listener != NULL);
+
+	message = dbus_message_new_signal (GS_LISTENER_PATH,
+	                                   GS_LISTENER_SERVICE,
+	                                   name);
+
+	dbus_message_iter_init_append (message, &iter);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &value);
+
+	if (! send_dbus_message (listener->priv->connection, message))
+	{
+		gs_debug ("Could not send %s signal", name);
+	}
+
+	dbus_message_unref (message);
+}
+
+static void
+gs_listener_send_signal_active_changed (GSListener *listener)
+{
+	g_return_if_fail (listener != NULL);
+
+	gs_debug ("Sending the ActiveChanged(%s) signal on the session bus",
+	          listener->priv->active ? "TRUE" : "FALSE");
+
+	send_dbus_boolean_signal (listener, "ActiveChanged", listener->priv->active);
+}
+
+static const char *
+get_name_for_entry_type (int entry_type)
+{
+	const char *name;
+
+	switch (entry_type)
+	{
+	case REF_ENTRY_TYPE_INHIBIT:
+		name = "inhibitor";
+		break;
+	case REF_ENTRY_TYPE_THROTTLE:
+		name = "throttler";
+		break;
+	default:
+		g_assert_not_reached ();
+		break;
+	}
+
+	return name;
+}
+
+static GHashTable *
+get_hash_for_entry_type (GSListener         *listener,
+                         int                 entry_type)
+{
+	GHashTable *hash;
+
+	switch (entry_type)
+	{
+	case REF_ENTRY_TYPE_INHIBIT:
+		hash = listener->priv->inhibitors;
+		break;
+	case REF_ENTRY_TYPE_THROTTLE:
+		hash = listener->priv->throttlers;
+		break;
+	default:
+		g_assert_not_reached ();
+		break;
+	}
+
+	return hash;
+}
+
+static void
+list_ref_entry (gpointer key,
+                gpointer value,
+                gpointer user_data)
+{
+	GSListenerRefEntry *entry;
+
+	entry =  (GSListenerRefEntry *)value;
+
+	gs_debug ("%s: %s for reason: %s",
+	          get_name_for_entry_type (entry->entry_type),
+	          entry->application,
+	          entry->reason);
+}
+
+static gboolean
+listener_ref_entry_is_present (GSListener *listener,
+                               int         entry_type)
+{
+	guint       n_entries;
+	gboolean    is_set;
+	GHashTable *hash;
+
+	hash = get_hash_for_entry_type (listener, entry_type);
+
+	/* if we aren't inhibited then activate */
+	n_entries = 0;
+	if (hash != NULL)
+	{
+		n_entries = g_hash_table_size (hash);
+
+		g_hash_table_foreach (hash, list_ref_entry, NULL);
+	}
+
+	is_set = (n_entries > 0);
+
+	return is_set;
+}
+
+static gboolean
+listener_check_activation (GSListener *listener)
+{
+	gboolean inhibited;
+	gboolean res;
+
+	gs_debug ("Checking for activation");
+
+	if (! listener->priv->activation_enabled)
+	{
+		return TRUE;
+	}
+
+	if (! listener->priv->session_idle)
+	{
+		return TRUE;
+	}
+
+	/* if we aren't inhibited then activate */
+	inhibited = listener_ref_entry_is_present (listener, REF_ENTRY_TYPE_INHIBIT);
+
+	res = FALSE;
+	if (! inhibited)
+	{
+		gs_debug ("Trying to activate");
+		res = gs_listener_set_active (listener, TRUE);
+	}
+
+	return res;
+}
+
+static void
+gs_listener_set_throttle (GSListener *listener,
+                          gboolean    throttled)
+{
+	g_return_if_fail (GS_IS_LISTENER (listener));
+
+	if (listener->priv->throttled != throttled)
+	{
+		gs_debug ("Changing throttle status: %d", throttled);
+
+		listener->priv->throttled = (throttled != FALSE);
+
+		g_signal_emit (listener, signals [THROTTLE_CHANGED], 0, throttled);
+	}
+}
+
+static gboolean
+listener_check_throttle (GSListener *listener)
+{
+	gboolean throttled;
+
+	gs_debug ("Checking for throttle");
+
+	throttled = listener_ref_entry_is_present (listener, REF_ENTRY_TYPE_THROTTLE);
+
+	if (throttled != listener->priv->throttled)
+	{
+		gs_listener_set_throttle (listener, throttled);
+	}
+
+	return TRUE;
+}
+
+static gboolean
+listener_set_session_idle_internal (GSListener *listener,
+                                    gboolean    idle)
+{
+	listener->priv->session_idle = (idle != FALSE);
+
+	if (idle)
+	{
+		listener->priv->session_idle_start = time (NULL);
+	}
+	else
+	{
+		listener->priv->session_idle_start = 0;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+listener_set_active_internal (GSListener *listener,
+                              gboolean    active)
+{
+	listener->priv->active = (active != FALSE);
+
+	/* if idle not in sync with active, change it */
+	if (listener->priv->session_idle != active)
+	{
+		listener_set_session_idle_internal (listener, active);
+	}
+
+	if (active)
+	{
+		listener->priv->active_start = time (NULL);
+	}
+	else
+	{
+		listener->priv->active_start = 0;
+	}
+
+	gs_listener_send_signal_active_changed (listener);
+
+	return TRUE;
+}
+
+gboolean
+gs_listener_set_active (GSListener *listener,
+                        gboolean    active)
+{
+	gboolean res;
+
+	g_return_val_if_fail (GS_IS_LISTENER (listener), FALSE);
+
+	if (listener->priv->active == active)
+	{
+		gs_debug ("Trying to set active state when already: %s",
+		          active ? "active" : "inactive");
+		return FALSE;
+	}
+
+	res = FALSE;
+	g_signal_emit (listener, signals [ACTIVE_CHANGED], 0, active, &res);
+	if (! res)
+	{
+		/* if the signal is not handled then we haven't changed state */
+		gs_debug ("Active-changed signal not handled");
+
+		/* clear the idle state */
+		if (active)
+		{
+			listener_set_session_idle_internal (listener, FALSE);
+		}
+
+		return FALSE;
+	}
+
+	listener_set_active_internal (listener, active);
+
+	return TRUE;
+}
+
+gboolean
+gs_listener_set_session_idle (GSListener *listener,
+                              gboolean    idle)
+{
+	gboolean res;
+
+	g_return_val_if_fail (GS_IS_LISTENER (listener), FALSE);
+
+	gs_debug ("Setting session idle: %d", idle);
+
+	if (listener->priv->session_idle == idle)
+	{
+		gs_debug ("Trying to set idle state when already %s",
+		          idle ? "idle" : "not idle");
+		return FALSE;
+	}
+
+	if (idle)
+	{
+		gboolean inhibited;
+
+		inhibited = listener_ref_entry_is_present (listener, REF_ENTRY_TYPE_INHIBIT);
+
+		/* if we are inhibited then do nothing */
+		if (inhibited)
+		{
+			return FALSE;
+		}
+	}
+
+	listener->priv->session_idle = (idle != FALSE);
+	res = listener_check_activation (listener);
+
+	/* if activation fails then don't set idle */
+	if (res)
+	{
+		listener_set_session_idle_internal (listener, idle);
+	}
+	else
+	{
+		gs_debug ("Idle activation failed");
+		listener->priv->session_idle = !idle;
+	}
+
+	return res;
+}
+
+gboolean
+gs_listener_get_activation_enabled (GSListener *listener)
+{
+	g_return_val_if_fail (GS_IS_LISTENER (listener), FALSE);
+
+	return listener->priv->activation_enabled;
+}
+
+gboolean
+gs_listener_is_inhibited (GSListener *listener)
+{
+	gboolean inhibited;
+
+	g_return_val_if_fail (GS_IS_LISTENER (listener), FALSE);
+
+	inhibited = listener_ref_entry_is_present (listener, REF_ENTRY_TYPE_INHIBIT);
+
+	return inhibited;
+}
+
+void
+gs_listener_set_activation_enabled (GSListener *listener,
+                                    gboolean    enabled)
+{
+	g_return_if_fail (GS_IS_LISTENER (listener));
+
+	if (listener->priv->activation_enabled != enabled)
+	{
+		listener->priv->activation_enabled = (enabled != FALSE);
+	}
+}
+
+static dbus_bool_t
+listener_property_set_bool (GSListener *listener,
+                            guint       prop_id,
+                            dbus_bool_t value)
+{
+	dbus_bool_t ret;
+
+	ret = FALSE;
+
+	switch (prop_id)
+	{
+	case PROP_ACTIVE:
+		gs_listener_set_active (listener, value);
+		ret = TRUE;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static void
+raise_error (DBusConnection *connection,
+             DBusMessage    *in_reply_to,
+             const char     *error_name,
+             char           *format, ...)
+{
+	char         buf[512];
+	DBusMessage *reply;
+
+	va_list args;
+	va_start (args, format);
+	vsnprintf (buf, sizeof (buf), format, args);
+	va_end (args);
+
+	gs_debug (buf);
+	reply = dbus_message_new_error (in_reply_to, error_name, buf);
+	if (reply == NULL)
+	{
+		g_error ("No memory");
+	}
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+}
+
+static void
+raise_syntax (DBusConnection *connection,
+              DBusMessage    *in_reply_to,
+              const char     *method_name)
+{
+	raise_error (connection, in_reply_to,
+	             GS_LISTENER_SERVICE ".SyntaxError",
+	             "There is a syntax error in the invocation of the method %s",
+	             method_name);
+}
+
+static guint32
+generate_cookie (void)
+{
+	guint32 cookie;
+
+	cookie = (guint32)g_random_int_range (1, G_MAXINT32);
+
+	return cookie;
+}
+
+static guint32
+listener_generate_unique_key (GSListener *listener,
+                              int         entry_type)
+{
+	guint32     cookie;
+	GHashTable *hash;
+
+	hash = get_hash_for_entry_type (listener, entry_type);
+
+	do
+	{
+		cookie = generate_cookie ();
+	}
+	while (g_hash_table_lookup (hash, &cookie) != NULL);
+
+	return cookie;
+}
+
+static void
+listener_ref_entry_check (GSListener *listener,
+                          int         entry_type)
+{
+	switch (entry_type)
+	{
+	case REF_ENTRY_TYPE_INHIBIT:
+		listener_check_activation (listener);
+		break;
+	case REF_ENTRY_TYPE_THROTTLE:
+		listener_check_throttle (listener);
+		break;
+	default:
+		g_assert_not_reached ();
+		break;
+	}
+}
+
+static void
+add_session_inhibit (GSListener         *listener,
+                     GSListenerRefEntry *entry)
+{
+	DBusMessage    *message;
+	DBusMessage    *reply;
+	DBusMessageIter iter;
+	DBusMessageIter reply_iter;
+	DBusError       error;
+	guint           xid;
+	guint           flags;
+
+	g_return_if_fail (listener != NULL);
+
+	dbus_error_init (&error);
+
+	message = dbus_message_new_method_call (SESSION_NAME,
+	                                        SESSION_PATH,
+	                                        SESSION_INTERFACE,
+	                                        "Inhibit");
+	if (message == NULL)
+	{
+		gs_debug ("Couldn't allocate the dbus message");
+		return;
+	}
+
+	dbus_message_iter_init_append (message, &iter);
+	xid = 0;
+	flags = 8;
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &entry->application);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &xid);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &entry->reason);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &flags);
+
+	/* FIXME: use async? */
+	reply = dbus_connection_send_with_reply_and_block (listener->priv->connection,
+	        message,
+	        -1,
+	        &error);
+	dbus_message_unref (message);
+
+	if (dbus_error_is_set (&error))
+	{
+		gs_debug ("%s raised:\n %s\n\n", error.name, error.message);
+		dbus_error_free (&error);
+		return;
+	}
+
+	dbus_message_iter_init (reply, &reply_iter);
+	dbus_message_iter_get_basic (&reply_iter, &entry->foreign_cookie);
+
+	dbus_message_unref (reply);
+}
+
+static void
+remove_session_inhibit (GSListener         *listener,
+                        GSListenerRefEntry *entry)
+{
+	DBusMessage    *message;
+	DBusMessage    *reply;
+	DBusMessageIter iter;
+	DBusError       error;
+
+	g_return_if_fail (listener != NULL);
+
+	if (entry->foreign_cookie == 0)
+	{
+		gs_debug ("Can't remove inhibitor from session: Session cookie not set");
+		return;
+	}
+
+	dbus_error_init (&error);
+
+	message = dbus_message_new_method_call (SESSION_NAME,
+	                                        SESSION_PATH,
+	                                        SESSION_INTERFACE,
+	                                        "Uninhibit");
+	if (message == NULL)
+	{
+		gs_debug ("Couldn't allocate the dbus message");
+		return;
+	}
+
+	dbus_message_iter_init_append (message, &iter);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &entry->foreign_cookie);
+
+	/* FIXME: use async? */
+	reply = dbus_connection_send_with_reply_and_block (listener->priv->connection,
+	        message,
+	        -1,
+	        &error);
+	dbus_message_unref (message);
+
+	if (dbus_error_is_set (&error))
+	{
+		gs_debug ("%s raised:\n %s\n\n", error.name, error.message);
+		dbus_error_free (&error);
+		return;
+	}
+
+	dbus_message_unref (reply);
+}
+
+static void
+listener_add_ref_entry (GSListener         *listener,
+                        int                 entry_type,
+                        GSListenerRefEntry *entry)
+{
+	GHashTable *hash;
+
+	gs_debug ("adding %s from %s for reason '%s' on connection %s",
+	          get_name_for_entry_type (entry_type),
+	          entry->application,
+	          entry->reason,
+	          entry->connection);
+
+	hash = get_hash_for_entry_type (listener, entry_type);
+	g_hash_table_insert (hash, &entry->cookie, entry);
+
+	if (entry_type == REF_ENTRY_TYPE_INHIBIT)
+	{
+		/* proxy inhibit over to mate session */
+		add_session_inhibit (listener, entry);
+	}
+
+	listener_ref_entry_check (listener, entry_type);
+}
+
+static gboolean
+listener_remove_ref_entry (GSListener *listener,
+                           int         entry_type,
+                           guint32     cookie)
+{
+	GHashTable         *hash;
+	gboolean            removed;
+	GSListenerRefEntry *entry;
+
+	removed = FALSE;
+
+	hash = get_hash_for_entry_type (listener, entry_type);
+
+	entry = g_hash_table_lookup (hash, &cookie);
+	if (entry == NULL)
+	{
+		goto out;
+	}
+
+	gs_debug ("removing %s from %s for reason '%s' on connection %s",
+	          get_name_for_entry_type (entry_type),
+	          entry->application,
+	          entry->reason,
+	          entry->connection);
+
+	if (entry_type == REF_ENTRY_TYPE_INHIBIT)
+	{
+		/* remove inhibit from mate session */
+		remove_session_inhibit (listener, entry);
+	}
+
+	removed = g_hash_table_remove (hash, &cookie);
+out:
+	if (removed)
+	{
+		listener_ref_entry_check (listener, entry_type);
+	}
+	else
+	{
+		gs_debug ("Cookie %u was not in the list!", cookie);
+	}
+
+	return removed;
+}
+
+static void
+accumulate_ref_entry (gpointer            key,
+                      GSListenerRefEntry *entry,
+                      DBusMessageIter    *iter)
+{
+	GDateTime *dt;
+	char *description;
+	char *time;
+
+	dt = g_date_time_new_from_unix_utc (entry->since);
+	time = g_date_time_format_iso8601 (dt);
+
+	description = g_strdup_printf ("Application=\"%s\"; Since=\"%s\"; Reason=\"%s\";",
+	                               entry->application,
+	                               time,
+	                               entry->reason);
+
+	dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &description);
+
+	g_free (description);
+	g_free (time);
+	g_date_time_unref (dt);
+}
+
+static DBusHandlerResult
+listener_dbus_get_ref_entries (GSListener     *listener,
+                               int             entry_type,
+                               DBusConnection *connection,
+                               DBusMessage    *message)
+{
+	DBusMessage        *reply;
+	GHashTable         *hash;
+	DBusMessageIter     iter;
+	DBusMessageIter     iter_array;
+
+	hash = get_hash_for_entry_type (listener, entry_type);
+
+	reply = dbus_message_new_method_return (message);
+	if (reply == NULL)
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_iter_init_append (reply, &iter);
+	dbus_message_iter_open_container (&iter,
+	                                  DBUS_TYPE_ARRAY,
+	                                  DBUS_TYPE_STRING_AS_STRING,
+	                                  &iter_array);
+
+	if (hash != NULL)
+	{
+		g_hash_table_foreach (hash,
+		                      (GHFunc)accumulate_ref_entry,
+		                      &iter_array);
+	}
+
+	dbus_message_iter_close_container (&iter, &iter_array);
+
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+#ifdef WITH_CONSOLE_KIT
+static void
+listener_add_ck_ref_entry (GSListener     *listener,
+                           int             entry_type,
+                           DBusConnection *connection,
+                           DBusMessage    *message,
+                           guint32        *cookiep)
+{
+	GSListenerRefEntry *entry;
+
+	entry = g_new0 (GSListenerRefEntry, 1);
+	entry->entry_type = entry_type;
+	entry->connection = g_strdup (dbus_message_get_sender (message));
+	entry->cookie = listener_generate_unique_key (listener, entry_type);
+	entry->application = g_strdup ("ConsoleKit");
+	entry->reason = g_strdup ("Session is not active");
+	entry->since = g_get_real_time () / G_USEC_PER_SEC;
+
+	/* takes ownership of entry */
+	listener_add_ref_entry (listener, entry_type, entry);
+
+	if (cookiep != NULL)
+	{
+		*cookiep = entry->cookie;
+	}
+}
+
+static void
+listener_remove_ck_ref_entry (GSListener *listener,
+                              int         entry_type,
+                              guint32     cookie)
+{
+	listener_remove_ref_entry (listener, entry_type, cookie);
+}
+#endif
+
+static DBusHandlerResult
+listener_dbus_add_ref_entry (GSListener     *listener,
+                             int             entry_type,
+                             DBusConnection *connection,
+                             DBusMessage    *message)
+{
+	DBusMessage        *reply;
+	DBusError           error;
+	const char         *application;
+	const char         *reason;
+	GSListenerRefEntry *entry;
+	DBusMessageIter     iter;
+
+	dbus_error_init (&error);
+	if (! dbus_message_get_args (message, &error,
+	                             DBUS_TYPE_STRING, &application,
+	                             DBUS_TYPE_STRING, &reason,
+	                             DBUS_TYPE_INVALID))
+	{
+		if (entry_type == REF_ENTRY_TYPE_INHIBIT)
+		{
+			raise_syntax (connection, message, "Inhibit");
+		}
+		else if (entry_type == REF_ENTRY_TYPE_THROTTLE)
+		{
+			raise_syntax (connection, message, "Throttle");
+		}
+		else
+		{
+			g_assert_not_reached ();
+		}
+
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	reply = dbus_message_new_method_return (message);
+	if (reply == NULL)
+	{
+		g_error ("No memory");
+	}
+
+	entry = g_new0 (GSListenerRefEntry, 1);
+	entry->entry_type = entry_type;
+	entry->connection = g_strdup (dbus_message_get_sender (message));
+	entry->cookie = listener_generate_unique_key (listener, entry_type);
+	entry->application = g_strdup (application);
+	entry->reason = g_strdup (reason);
+	entry->since = g_get_real_time () / G_USEC_PER_SEC;
+
+	listener_add_ref_entry (listener, entry_type, entry);
+
+	dbus_message_iter_init_append (reply, &iter);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &entry->cookie);
+
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+listener_dbus_remove_ref_entry (GSListener     *listener,
+                                int             entry_type,
+                                DBusConnection *connection,
+                                DBusMessage    *message)
+{
+	DBusMessage        *reply;
+	DBusError           error;
+	guint32             cookie;
+
+	dbus_error_init (&error);
+	if (! dbus_message_get_args (message, &error,
+	                             DBUS_TYPE_UINT32, &cookie,
+	                             DBUS_TYPE_INVALID))
+	{
+		if (entry_type == REF_ENTRY_TYPE_INHIBIT)
+		{
+			raise_syntax (connection, message, "UnInhibit");
+		}
+		else if (entry_type == REF_ENTRY_TYPE_THROTTLE)
+		{
+			raise_syntax (connection, message, "UnThrottle");
+		}
+		else
+		{
+			g_assert_not_reached ();
+		}
+
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	reply = dbus_message_new_method_return (message);
+	if (reply == NULL)
+		g_error ("No memory");
+
+	/* FIXME: check sender is from same connection as entry */
+	dbus_message_get_sender (message);
+
+	listener_remove_ref_entry (listener, entry_type, cookie);
+
+	/* FIXME:  Pointless? */
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static gboolean
+listener_ref_entry_remove_for_connection (GSListener  *listener,
+        int          entry_type,
+        const char  *connection)
+{
+	gboolean    removed;
+	GHashTable *hash;
+	GHashTableIter iter;
+	GSListenerRefEntry *entry;
+
+	if (connection == NULL)
+		return FALSE;
+
+	hash = get_hash_for_entry_type (listener, entry_type);
+
+	removed = FALSE;
+	g_hash_table_iter_init (&iter, hash);
+	while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&entry))
+	{
+		if (entry->connection != NULL &&
+		        strcmp (connection, entry->connection) == 0)
+		{
+			gs_debug ("removing %s from %s for reason '%s' on connection %s",
+			          get_name_for_entry_type (entry->entry_type),
+			          entry->application,
+			          entry->reason,
+			          entry->connection);
+
+			if (entry->entry_type == REF_ENTRY_TYPE_INHIBIT)
+			{
+				/* remove inhibit from mate session */
+				remove_session_inhibit (listener, entry);
+			}
+
+			g_hash_table_iter_remove (&iter);
+			removed = TRUE;
+		}
+	}
+
+	return removed;
+}
+
+static void
+listener_service_deleted (GSListener  *listener,
+                          DBusMessage *message)
+{
+	const char *old_service_name;
+	const char *new_service_name;
+	gboolean    removed;
+
+	if (! dbus_message_get_args (message, NULL,
+	                             DBUS_TYPE_STRING, &old_service_name,
+	                             DBUS_TYPE_STRING, &new_service_name,
+	                             DBUS_TYPE_INVALID))
+	{
+		g_error ("Invalid NameOwnerChanged signal from bus!");
+		return;
+	}
+
+	gs_debug ("DBUS service deleted: %s", new_service_name);
+
+	removed = listener_ref_entry_remove_for_connection (listener, REF_ENTRY_TYPE_THROTTLE, new_service_name);
+	if (removed)
+	{
+		listener_ref_entry_check (listener, REF_ENTRY_TYPE_THROTTLE);
+	}
+
+	removed = listener_ref_entry_remove_for_connection (listener, REF_ENTRY_TYPE_INHIBIT, new_service_name);
+	if (removed)
+	{
+		listener_ref_entry_check (listener, REF_ENTRY_TYPE_INHIBIT);
+	}
+
+}
+
+static void
+raise_property_type_error (DBusConnection *connection,
+                           DBusMessage    *in_reply_to,
+                           const char     *device_id)
+{
+	char         buf [512];
+	DBusMessage *reply;
+
+	snprintf (buf, 511,
+	          "Type mismatch setting property with id %s",
+	          device_id);
+	gs_debug (buf);
+
+	reply = dbus_message_new_error (in_reply_to,
+	                                TYPE_MISMATCH_ERROR,
+	                                buf);
+	if (reply == NULL)
+	{
+		g_error ("No memory");
+	}
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+}
+
+static DBusHandlerResult
+listener_set_property (GSListener     *listener,
+                       DBusConnection *connection,
+                       DBusMessage    *message,
+                       guint           prop_id)
+{
+	const char     *path;
+	int             type;
+	gboolean        rc;
+	DBusMessageIter iter;
+	DBusMessage    *reply;
+
+	path = dbus_message_get_path (message);
+
+	dbus_message_iter_init (message, &iter);
+	type = dbus_message_iter_get_arg_type (&iter);
+	rc = FALSE;
+
+	switch (type)
+	{
+	case DBUS_TYPE_BOOLEAN:
+	{
+		dbus_bool_t v;
+		dbus_message_iter_get_basic (&iter, &v);
+		rc = listener_property_set_bool (listener, prop_id, v);
+		break;
+	}
+	default:
+		gs_debug ("Unsupported property type %d", type);
+		break;
+	}
+
+	if (! rc)
+	{
+		raise_property_type_error (connection, message, path);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	reply = dbus_message_new_method_return (message);
+
+	if (reply == NULL)
+	{
+		g_error ("No memory");
+	}
+
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+listener_get_property (GSListener     *listener,
+                       DBusConnection *connection,
+                       DBusMessage    *message,
+                       guint           prop_id)
+{
+	DBusMessageIter iter;
+	DBusMessage    *reply;
+
+	reply = dbus_message_new_method_return (message);
+
+	dbus_message_iter_init_append (reply, &iter);
+
+	if (reply == NULL)
+		g_error ("No memory");
+
+	switch (prop_id)
+	{
+	case PROP_ACTIVE:
+	{
+		dbus_bool_t b;
+		b = listener->priv->active;
+		dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &b);
+	}
+	break;
+	default:
+		gs_debug ("Unsupported property id %u", prop_id);
+		break;
+	}
+
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+listener_get_active_time (GSListener     *listener,
+                          DBusConnection *connection,
+                          DBusMessage    *message)
+{
+	DBusMessageIter iter;
+	DBusMessage    *reply;
+	dbus_uint32_t    secs;
+
+	reply = dbus_message_new_method_return (message);
+
+	dbus_message_iter_init_append (reply, &iter);
+
+	if (reply == NULL)
+	{
+		g_error ("No memory");
+	}
+
+	if (listener->priv->active)
+	{
+		time_t now = time (NULL);
+
+		if (now < listener->priv->active_start)
+		{
+			/* shouldn't happen */
+			gs_debug ("Active start time is in the future");
+			secs = 0;
+		}
+		else if (listener->priv->active_start <= 0)
+		{
+			/* shouldn't happen */
+			gs_debug ("Active start time was not set");
+			secs = 0;
+		}
+		else
+		{
+			secs = now - listener->priv->active_start;
+		}
+	}
+	else
+	{
+		secs = 0;
+	}
+
+	gs_debug ("Returning screensaver active for %u seconds", secs);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &secs);
+
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+listener_show_message (GSListener     *listener,
+                       DBusConnection *connection,
+                       DBusMessage    *message)
+{
+	DBusMessageIter iter;
+	DBusMessage    *reply;
+	DBusError       error;
+
+	reply = dbus_message_new_method_return (message);
+
+	dbus_message_iter_init_append (reply, &iter);
+
+	if (reply == NULL)
+	{
+		g_error ("No memory");
+	}
+
+	if (listener->priv->active)
+	{
+		char *summary;
+		char *body;
+		char *icon;
+
+		/* if we're not active we ignore the request */
+
+		dbus_error_init (&error);
+		if (! dbus_message_get_args (message, &error,
+		                             DBUS_TYPE_STRING, &summary,
+		                             DBUS_TYPE_STRING, &body,
+		                             DBUS_TYPE_STRING, &icon,
+		                             DBUS_TYPE_INVALID))
+		{
+			raise_syntax (connection, message, "ShowMessage");
+			return DBUS_HANDLER_RESULT_HANDLED;
+		}
+
+		g_signal_emit (listener, signals [SHOW_MESSAGE], 0, summary, body, icon);
+	}
+
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+do_introspect (DBusConnection *connection,
+               DBusMessage    *message,
+               dbus_bool_t     local_interface)
+{
+	DBusMessage *reply;
+	GString     *xml;
+	char        *xml_string;
+
+	/* standard header */
+	xml = g_string_new ("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
+	                    "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
+	                    "<node>\n"
+	                    "  <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+	                    "    <method name=\"Introspect\">\n"
+	                    "      <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
+	                    "    </method>\n"
+	                    "  </interface>\n");
+
+	/* ScreenSaver interface */
+	xml = g_string_append (xml,
+	                       "  <interface name=\"org.mate.ScreenSaver\">\n"
+	                       "    <method name=\"Lock\">\n"
+	                       "    </method>\n"
+	                       "    <method name=\"Unlock\">\n"
+	                       "    </method>\n"
+	                       "    <method name=\"Cycle\">\n"
+	                       "    </method>\n"
+	                       "    <method name=\"SimulateUserActivity\">\n"
+	                       "    </method>\n"
+	                       "    <method name=\"Inhibit\">\n"
+	                       "      <arg name=\"application_name\" direction=\"in\" type=\"s\"/>\n"
+	                       "      <arg name=\"reason\" direction=\"in\" type=\"s\"/>\n"
+	                       "      <arg name=\"cookie\" direction=\"out\" type=\"u\"/>\n"
+	                       "    </method>\n"
+	                       "    <method name=\"UnInhibit\">\n"
+	                       "      <arg name=\"cookie\" direction=\"in\" type=\"u\"/>\n"
+	                       "    </method>\n"
+	                       "    <method name=\"GetInhibitors\">\n"
+	                       "      <arg name=\"list\" direction=\"out\" type=\"as\"/>\n"
+	                       "    </method>\n"
+	                       "    <method name=\"Throttle\">\n"
+	                       "      <arg name=\"application_name\" direction=\"in\" type=\"s\"/>\n"
+	                       "      <arg name=\"reason\" direction=\"in\" type=\"s\"/>\n"
+	                       "      <arg name=\"cookie\" direction=\"out\" type=\"u\"/>\n"
+	                       "    </method>\n"
+	                       "    <method name=\"UnThrottle\">\n"
+	                       "      <arg name=\"cookie\" direction=\"in\" type=\"u\"/>\n"
+	                       "    </method>\n"
+	                       "    <method name=\"GetActive\">\n"
+	                       "      <arg name=\"value\" direction=\"out\" type=\"b\"/>\n"
+	                       "    </method>\n"
+	                       "    <method name=\"GetActiveTime\">\n"
+	                       "      <arg name=\"seconds\" direction=\"out\" type=\"u\"/>\n"
+	                       "    </method>\n"
+	                       "    <method name=\"SetActive\">\n"
+	                       "      <arg name=\"value\" direction=\"in\" type=\"b\"/>\n"
+	                       "    </method>\n"
+	                       "    <method name=\"ShowMessage\">\n"
+	                       "      <arg name=\"summary\" direction=\"in\" type=\"s\"/>\n"
+	                       "      <arg name=\"body\" direction=\"in\" type=\"s\"/>\n"
+	                       "      <arg name=\"icon\" direction=\"in\" type=\"s\"/>\n"
+	                       "    </method>\n"
+	                       "    <signal name=\"ActiveChanged\">\n"
+	                       "      <arg name=\"new_value\" type=\"b\"/>\n"
+	                       "    </signal>\n"
+	                       "  </interface>\n");
+
+	reply = dbus_message_new_method_return (message);
+
+	xml = g_string_append (xml, "</node>\n");
+	xml_string = g_string_free (xml, FALSE);
+
+	dbus_message_append_args (reply,
+	                          DBUS_TYPE_STRING, &xml_string,
+	                          DBUS_TYPE_INVALID);
+
+	g_free (xml_string);
+
+	if (reply == NULL)
+	{
+		g_error ("No memory");
+	}
+
+	if (! dbus_connection_send (connection, reply, NULL))
+	{
+		g_error ("No memory");
+	}
+
+	dbus_message_unref (reply);
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+listener_dbus_handle_session_message (DBusConnection *connection,
+                                      DBusMessage    *message,
+                                      void           *user_data,
+                                      dbus_bool_t     local_interface)
+{
+	GSListener *listener = GS_LISTENER (user_data);
+
+#if 0
+	g_message ("obj_path=%s interface=%s method=%s destination=%s",
+	           dbus_message_get_path (message),
+	           dbus_message_get_interface (message),
+	           dbus_message_get_member (message),
+	           dbus_message_get_destination (message));
+#endif
+
+	g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+	g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "Lock"))
+	{
+		g_signal_emit (listener, signals [LOCK], 0);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "Unlock"))
+	{
+		gs_listener_set_active (listener, FALSE);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "Quit"))
+	{
+		g_signal_emit (listener, signals [QUIT], 0);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "Cycle"))
+	{
+		g_signal_emit (listener, signals [CYCLE], 0);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "Inhibit"))
+	{
+		return listener_dbus_add_ref_entry (listener, REF_ENTRY_TYPE_INHIBIT, connection, message);
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "UnInhibit"))
+	{
+		return listener_dbus_remove_ref_entry (listener, REF_ENTRY_TYPE_INHIBIT, connection, message);
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "GetInhibitors"))
+	{
+		return listener_dbus_get_ref_entries (listener, REF_ENTRY_TYPE_INHIBIT, connection, message);
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "Throttle"))
+	{
+		return listener_dbus_add_ref_entry (listener, REF_ENTRY_TYPE_THROTTLE, connection, message);
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "UnThrottle"))
+	{
+		return listener_dbus_remove_ref_entry (listener, REF_ENTRY_TYPE_THROTTLE, connection, message);
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "SetActive"))
+	{
+		return listener_set_property (listener, connection, message, PROP_ACTIVE);
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "GetActive"))
+	{
+		return listener_get_property (listener, connection, message, PROP_ACTIVE);
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "GetActiveTime"))
+	{
+		return listener_get_active_time (listener, connection, message);
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "ShowMessage"))
+	{
+		return listener_show_message (listener, connection, message);
+	}
+	if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "SimulateUserActivity"))
+	{
+		g_signal_emit (listener, signals [SIMULATE_USER_ACTIVITY], 0);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+	if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect"))
+	{
+		return do_introspect (connection, message, local_interface);
+	}
+
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static gboolean
+_listener_message_path_is_our_session (GSListener  *listener,
+                                       DBusMessage *message)
+{
+	const char *ssid;
+
+	ssid = dbus_message_get_path (message);
+
+	if (ssid == NULL)
+		return FALSE;
+
+	if (listener->priv->session_id == NULL)
+		return FALSE;
+
+	if (strcmp (ssid, listener->priv->session_id) == 0)
+		return TRUE;
+
+	return FALSE;
+}
+
+#ifdef WITH_SYSTEMD
+static gboolean
+properties_changed_match (DBusMessage *message,
+			  const char  *property)
+{
+	DBusMessageIter iter, sub, sub2;
+
+	/* Checks whether a certain property is listed in the
+	 * specified PropertiesChanged message */
+
+	if (!dbus_message_iter_init (message, &iter))
+		goto failure;
+
+	/* Jump over interface name */
+	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
+		goto failure;
+
+	dbus_message_iter_next (&iter);
+
+	/* First, iterate through the changed properties array */
+	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY ||
+	    dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_DICT_ENTRY)
+		goto failure;
+
+	dbus_message_iter_recurse (&iter, &sub);
+	while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) {
+		const char *name;
+
+		if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_DICT_ENTRY)
+			goto failure;
+
+		dbus_message_iter_recurse (&sub, &sub2);
+		dbus_message_iter_get_basic (&sub2, &name);
+
+		if (strcmp (name, property) == 0)
+			return TRUE;
+
+		dbus_message_iter_next (&sub);
+	}
+
+	dbus_message_iter_next (&iter);
+
+	/* Second, iterate through the invalidated properties array */
+	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY ||
+	    dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING)
+		goto failure;
+
+	dbus_message_iter_recurse (&iter, &sub);
+	while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) {
+		const char *name;
+
+		if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_STRING)
+			goto failure;
+
+		dbus_message_iter_get_basic (&sub, &name);
+
+		if (strcmp (name, property) == 0)
+			return TRUE;
+
+		dbus_message_iter_next (&sub);
+	}
+
+	return FALSE;
+
+failure:
+	gs_debug ("Failed to decode PropertiesChanged message.");
+	return FALSE;
+}
+
+static gint
+take_logind_inhibit_lock (DBusConnection *connection)
+{
+	DBusMessage    *message;
+	DBusMessage    *reply;
+	DBusError       error;
+	DBusMessageIter reply_iter;
+	gint            fd;
+
+	const char* what = "sleep";
+	const char* who  = g_get_user_name ();
+	const char* why  = "Lock screen before sleep";
+	const char* mode = "delay";
+
+	g_return_val_if_fail (connection != NULL, FALSE);
+
+	dbus_error_init (&error);
+
+	message = dbus_message_new_method_call (SYSTEMD_LOGIND_SERVICE,
+	                                        SYSTEMD_LOGIND_PATH,
+	                                        SYSTEMD_LOGIND_INTERFACE,
+	                                        "Inhibit");
+	if (message == NULL)
+	{
+		gs_debug ("Couldn't allocate the dbus message");
+		return 0;
+	}
+
+	if (dbus_message_append_args (message,
+	                              DBUS_TYPE_STRING, &what,
+	                              DBUS_TYPE_STRING, &who,
+	                              DBUS_TYPE_STRING, &why,
+	                              DBUS_TYPE_STRING, &mode,
+	                              DBUS_TYPE_INVALID) == FALSE)
+	{
+		gs_debug ("Couldn't add args to the dbus message");
+		return 0;
+	}
+
+	reply = dbus_connection_send_with_reply_and_block (connection, message,
+	                                                  -1, &error);
+	dbus_message_unref (message);
+
+	if (dbus_error_is_set (&error))
+	{
+		gs_debug ("%s raised:\n %s\n\n", error.name, error.message);
+		dbus_error_free (&error);
+		return 0;
+	}
+
+	dbus_message_iter_init (reply, &reply_iter);
+	dbus_message_iter_get_basic (&reply_iter, &fd);
+
+	dbus_message_unref (reply);
+
+	gs_debug ("System inhibitor fd is %d\n", fd);
+
+	return fd;
+}
+#endif
+
+static DBusHandlerResult
+listener_dbus_handle_system_message (DBusConnection *connection,
+                                     DBusMessage    *message,
+                                     void           *user_data,
+                                     dbus_bool_t     local_interface)
+{
+	GSListener *listener = GS_LISTENER (user_data);
+
+	g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+	g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+#if 1
+	gs_debug ("obj_path=%s interface=%s method=%s destination=%s",
+	          dbus_message_get_path (message),
+	          dbus_message_get_interface (message),
+	          dbus_message_get_member (message),
+	          dbus_message_get_destination (message));
+#endif
+
+#ifdef WITH_SYSTEMD
+	if (listener->priv->have_systemd) {
+
+		if (dbus_message_is_signal (message, SYSTEMD_LOGIND_SESSION_INTERFACE, "Unlock")) {
+			if (_listener_message_path_is_our_session (listener, message)) {
+				gs_debug ("systemd requested session unlock");
+				gs_listener_set_active (listener, FALSE);
+			}
+
+			return DBUS_HANDLER_RESULT_HANDLED;
+		} else if (dbus_message_is_signal (message, SYSTEMD_LOGIND_SESSION_INTERFACE, "Lock")) {
+			if (_listener_message_path_is_our_session (listener, message)) {
+				gs_debug ("systemd requested session lock");
+				g_signal_emit (listener, signals [LOCK], 0);
+			}
+
+			return DBUS_HANDLER_RESULT_HANDLED;
+		} else if (dbus_message_is_signal (message, SYSTEMD_LOGIND_INTERFACE, "PrepareForSleep")) {
+			gboolean  active = 0;
+			DBusError error;
+
+			dbus_error_init (&error);
+			dbus_message_get_args (message, &error, DBUS_TYPE_BOOLEAN, &active, DBUS_TYPE_INVALID);
+			if (active) {
+				gs_debug ("Logind wanted to sleep");
+				g_signal_emit (listener, signals [PREPARE_FOR_SLEEP], 0, active);
+				if (listener->priv->logind_inhibit_lock) {
+					gs_debug ("Releasing inihibitor lock");
+					close (listener->priv->logind_inhibit_lock);
+					listener->priv->logind_inhibit_lock = 0;
+				}
+			} else {
+				gs_debug ("Logind resumed from sleep");
+				listener->priv->logind_inhibit_lock = take_logind_inhibit_lock (listener->priv->system_connection);
+				g_signal_emit (listener, signals [PREPARE_FOR_SLEEP], 0, active);
+			}
+			gs_debug ("Logind PrepareForSleepHandled");
+
+			return DBUS_HANDLER_RESULT_HANDLED;
+		} else if (dbus_message_is_signal (message, DBUS_INTERFACE_PROPERTIES, "PropertiesChanged")) {
+
+			if (_listener_message_path_is_our_session (listener, message)) {
+
+				if (properties_changed_match (message, "Active")) {
+					gboolean new_active;
+
+					/* Instead of going via the
+					 * bus to read the new
+					 * property state, let's
+					 * shortcut this and ask
+					 * directly the low-level
+					 * information */
+
+					new_active = sd_session_is_active (listener->priv->session_id) != 0;
+					if (new_active)
+						g_signal_emit (listener, signals [SIMULATE_USER_ACTIVITY], 0);
+				}
+			}
+
+			return DBUS_HANDLER_RESULT_HANDLED;
+		}
+
+		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	}
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+
+	if (dbus_message_is_signal (message, CK_SESSION_INTERFACE, "Unlock"))
+	{
+		if (_listener_message_path_is_our_session (listener, message))
+		{
+			gs_debug ("Console kit requested session unlock");
+			gs_listener_set_active (listener, FALSE);
+		}
+
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+	else if (dbus_message_is_signal (message, CK_SESSION_INTERFACE, "Lock"))
+	{
+		if (_listener_message_path_is_our_session (listener, message))
+		{
+			gs_debug ("ConsoleKit requested session lock");
+			g_signal_emit (listener, signals [LOCK], 0);
+		}
+
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+	else if (dbus_message_is_signal (message, CK_SESSION_INTERFACE, "ActiveChanged"))
+	{
+		/* NB that `ActiveChanged' refers to the active
+		 * session in ConsoleKit terminology - ie which
+		 * session is currently displayed on the screen.
+		 * mate-screensaver uses `active' to mean `is the
+		 * screensaver active' (ie, is the screen locked) but
+		 * that's not what we're referring to here.
+		 */
+
+		if (_listener_message_path_is_our_session (listener, message))
+		{
+			DBusError   error;
+			dbus_bool_t new_active;
+
+			dbus_error_init (&error);
+			if (dbus_message_get_args (message, &error,
+			                           DBUS_TYPE_BOOLEAN, &new_active,
+			                           DBUS_TYPE_INVALID))
+			{
+				gs_debug ("ConsoleKit notified ActiveChanged %d", new_active);
+
+				/* when we aren't active add an implicit throttle from CK
+				 * when we become active remove the throttle and poke the lock */
+				if (new_active)
+				{
+					if (listener->priv->ck_throttle_cookie != 0)
+					{
+						listener_remove_ck_ref_entry (listener,
+						                              REF_ENTRY_TYPE_THROTTLE,
+						                              listener->priv->ck_throttle_cookie);
+						listener->priv->ck_throttle_cookie = 0;
+					}
+
+					g_signal_emit (listener, signals [SIMULATE_USER_ACTIVITY], 0);
+				}
+				else
+				{
+					if (listener->priv->ck_throttle_cookie != 0)
+					{
+						g_warning ("ConsoleKit throttle already set");
+						listener_remove_ck_ref_entry (listener,
+						                              REF_ENTRY_TYPE_THROTTLE,
+						                              listener->priv->ck_throttle_cookie);
+						listener->priv->ck_throttle_cookie = 0;
+					}
+
+					listener_add_ck_ref_entry (listener,
+					                           REF_ENTRY_TYPE_THROTTLE,
+					                           connection,
+					                           message,
+					                           &listener->priv->ck_throttle_cookie);
+				}
+			}
+
+			if (dbus_error_is_set (&error))
+			{
+				dbus_error_free (&error);
+			}
+		}
+
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+#endif
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusHandlerResult
+gs_listener_message_handler (DBusConnection *connection,
+                             DBusMessage    *message,
+                             void           *user_data)
+{
+	g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+	g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+#if 0
+	g_message ("obj_path=%s interface=%s method=%s destination=%s",
+	           dbus_message_get_path (message),
+	           dbus_message_get_interface (message),
+	           dbus_message_get_member (message),
+	           dbus_message_get_destination (message));
+#endif
+
+	if (dbus_message_is_method_call (message, "org.freedesktop.DBus", "AddMatch"))
+	{
+		DBusMessage *reply;
+
+		reply = dbus_message_new_method_return (message);
+
+		if (reply == NULL)
+		{
+			g_error ("No memory");
+		}
+
+		if (! dbus_connection_send (connection, reply, NULL))
+		{
+			g_error ("No memory");
+		}
+
+		dbus_message_unref (reply);
+
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+	else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") &&
+	         strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0)
+	{
+		dbus_connection_unref (connection);
+
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+	else
+	{
+		return listener_dbus_handle_session_message (connection, message, user_data, TRUE);
+	}
+}
+
+static gboolean
+gs_listener_dbus_init (GSListener *listener)
+{
+	DBusError error;
+
+	dbus_error_init (&error);
+
+	if (listener->priv->connection == NULL)
+	{
+		listener->priv->connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
+		if (listener->priv->connection == NULL)
+		{
+			if (dbus_error_is_set (&error))
+			{
+				gs_debug ("couldn't connect to session bus: %s",
+				          error.message);
+				dbus_error_free (&error);
+			}
+			return FALSE;
+		}
+
+		dbus_connection_setup_with_g_main (listener->priv->connection, NULL);
+		dbus_connection_set_exit_on_disconnect (listener->priv->connection, FALSE);
+	}
+
+	if (listener->priv->system_connection == NULL)
+	{
+		listener->priv->system_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+		if (listener->priv->system_connection == NULL)
+		{
+			if (dbus_error_is_set (&error))
+			{
+				gs_debug ("couldn't connect to system bus: %s",
+				          error.message);
+				dbus_error_free (&error);
+			}
+			return FALSE;
+		}
+
+		dbus_connection_setup_with_g_main (listener->priv->system_connection, NULL);
+		dbus_connection_set_exit_on_disconnect (listener->priv->system_connection, FALSE);
+	}
+
+	return TRUE;
+}
+
+static gboolean
+reinit_dbus (GSListener *listener)
+{
+	gboolean initialized;
+	gboolean try_again;
+
+	initialized = gs_listener_dbus_init (listener);
+
+	/* if we didn't initialize then try again */
+	/* FIXME: Should we keep trying forever?  If we fail more than
+	   once or twice then the session bus may have died.  The
+	   problem is that if it is restarted it will likely have a
+	   different bus address and we won't be able to find it */
+	try_again = !initialized;
+
+	return try_again;
+}
+
+static DBusHandlerResult
+listener_dbus_filter_function (DBusConnection *connection,
+                               DBusMessage    *message,
+                               void           *user_data)
+{
+	GSListener *listener = GS_LISTENER (user_data);
+	const char *path;
+
+	path = dbus_message_get_path (message);
+
+	/*
+	g_message ("obj_path=%s interface=%s method=%s",
+	           dbus_message_get_path (message),
+	           dbus_message_get_interface (message),
+	           dbus_message_get_member (message));
+	*/
+
+	if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")
+	        && strcmp (path, DBUS_PATH_LOCAL) == 0)
+	{
+
+		g_message ("Got disconnected from the session message bus; "
+		           "retrying to reconnect every 10 seconds");
+
+		dbus_connection_unref (connection);
+		listener->priv->connection = NULL;
+
+		g_timeout_add (10000, (GSourceFunc)reinit_dbus, listener);
+	}
+	else if (dbus_message_is_signal (message,
+	                                 DBUS_INTERFACE_DBUS,
+	                                 "NameOwnerChanged"))
+	{
+
+		if (listener->priv->inhibitors != NULL)
+		{
+			listener_service_deleted (listener, message);
+		}
+	}
+	else
+	{
+		return listener_dbus_handle_session_message (connection, message, user_data, FALSE);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+listener_dbus_system_filter_function (DBusConnection *connection,
+                                      DBusMessage    *message,
+                                      void           *user_data)
+{
+	GSListener *listener = GS_LISTENER (user_data);
+	const char *path;
+
+	path = dbus_message_get_path (message);
+
+	if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")
+	        && strcmp (path, DBUS_PATH_LOCAL) == 0)
+	{
+
+		g_message ("Got disconnected from the system message bus; "
+		           "retrying to reconnect every 10 seconds");
+
+		dbus_connection_unref (connection);
+		listener->priv->system_connection = NULL;
+
+		g_timeout_add (10000, (GSourceFunc)reinit_dbus, listener);
+	}
+	else
+	{
+		return listener_dbus_handle_system_message (connection, message, user_data, FALSE);
+	}
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+gs_listener_set_property (GObject            *object,
+                          guint               prop_id,
+                          const GValue       *value,
+                          GParamSpec         *pspec)
+{
+	GSListener *self;
+
+	self = GS_LISTENER (object);
+
+	switch (prop_id)
+	{
+	case PROP_ACTIVE:
+		gs_listener_set_active (self, g_value_get_boolean (value));
+		break;
+	case PROP_SESSION_IDLE:
+		gs_listener_set_session_idle (self, g_value_get_boolean (value));
+		break;
+	case PROP_ACTIVATION_ENABLED:
+		gs_listener_set_activation_enabled (self, g_value_get_boolean (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gs_listener_get_property (GObject            *object,
+                          guint               prop_id,
+                          GValue             *value,
+                          GParamSpec         *pspec)
+{
+	GSListener *self;
+
+	self = GS_LISTENER (object);
+
+	switch (prop_id)
+	{
+	case PROP_ACTIVE:
+		g_value_set_boolean (value, self->priv->active);
+		break;
+	case PROP_SESSION_IDLE:
+		g_value_set_boolean (value, self->priv->session_idle);
+		break;
+	case PROP_ACTIVATION_ENABLED:
+		g_value_set_boolean (value, self->priv->activation_enabled);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gs_listener_class_init (GSListenerClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize     = gs_listener_finalize;
+	object_class->get_property = gs_listener_get_property;
+	object_class->set_property = gs_listener_set_property;
+
+	signals [LOCK] =
+	    g_signal_new ("lock",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSListenerClass, lock),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0);
+	signals [QUIT] =
+	    g_signal_new ("quit",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSListenerClass, quit),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0);
+	signals [CYCLE] =
+	    g_signal_new ("cycle",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSListenerClass, cycle),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0);
+	signals [SIMULATE_USER_ACTIVITY] =
+	    g_signal_new ("simulate-user-activity",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSListenerClass, simulate_user_activity),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0);
+	signals [ACTIVE_CHANGED] =
+	    g_signal_new ("active-changed",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSListenerClass, active_changed),
+	                  NULL,
+	                  NULL,
+	                  gs_marshal_BOOLEAN__BOOLEAN,
+	                  G_TYPE_BOOLEAN,
+	                  1,
+	                  G_TYPE_BOOLEAN);
+	signals [THROTTLE_CHANGED] =
+	    g_signal_new ("throttle-changed",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSListenerClass, throttle_changed),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__BOOLEAN,
+	                  G_TYPE_NONE,
+	                  1,
+	                  G_TYPE_BOOLEAN);
+	signals [SHOW_MESSAGE] =
+	    g_signal_new ("show-message",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSListenerClass, show_message),
+	                  NULL,
+	                  NULL,
+	                  gs_marshal_VOID__STRING_STRING_STRING,
+	                  G_TYPE_NONE,
+	                  3,
+	                  G_TYPE_STRING,
+	                  G_TYPE_STRING,
+	                  G_TYPE_STRING);
+	signals [PREPARE_FOR_SLEEP] =
+	    g_signal_new ("prepare-for-sleep",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSListenerClass, prepare_for_sleep),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__BOOLEAN,
+	                  G_TYPE_NONE,
+	                  1,
+	                  G_TYPE_BOOLEAN);
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ACTIVE,
+	                                 g_param_spec_boolean ("active",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_ACTIVATION_ENABLED,
+	                                 g_param_spec_boolean ("activation-enabled",
+	                                         NULL,
+	                                         NULL,
+	                                         TRUE,
+	                                         G_PARAM_READWRITE));
+}
+
+static gboolean
+screensaver_is_running (DBusConnection *connection)
+{
+	DBusError error;
+	gboolean  exists;
+
+	g_return_val_if_fail (connection != NULL, FALSE);
+
+	dbus_error_init (&error);
+	exists = dbus_bus_name_has_owner (connection, GS_LISTENER_SERVICE, &error);
+	if (dbus_error_is_set (&error))
+	{
+		dbus_error_free (&error);
+	}
+
+	return exists;
+}
+
+gboolean
+gs_listener_acquire (GSListener *listener,
+                     GError    **error)
+{
+	int       acquired;
+	DBusError buserror;
+	gboolean  is_connected;
+
+	g_return_val_if_fail (listener != NULL, FALSE);
+
+	if (! listener->priv->connection)
+	{
+		g_set_error (error,
+		             GS_LISTENER_ERROR,
+		             GS_LISTENER_ERROR_ACQUISITION_FAILURE,
+		             "%s",
+		             _("failed to register with the message bus"));
+		return FALSE;
+	}
+
+	is_connected = dbus_connection_get_is_connected (listener->priv->connection);
+	if (! is_connected)
+	{
+		g_set_error (error,
+		             GS_LISTENER_ERROR,
+		             GS_LISTENER_ERROR_ACQUISITION_FAILURE,
+		             "%s",
+		             _("not connected to the message bus"));
+		return FALSE;
+	}
+
+	if (screensaver_is_running (listener->priv->connection))
+	{
+		g_set_error (error,
+		             GS_LISTENER_ERROR,
+		             GS_LISTENER_ERROR_ACQUISITION_FAILURE,
+		             "%s",
+		             _("screensaver already running in this session"));
+		return FALSE;
+	}
+
+	dbus_error_init (&buserror);
+
+	if (dbus_connection_register_object_path (listener->priv->connection,
+	        GS_LISTENER_PATH,
+	        &gs_listener_vtable,
+	        listener) == FALSE)
+	{
+		g_critical ("out of memory registering object path");
+		return FALSE;
+	}
+
+	acquired = dbus_bus_request_name (listener->priv->connection,
+	                                  GS_LISTENER_SERVICE,
+	                                  DBUS_NAME_FLAG_DO_NOT_QUEUE,
+	                                  &buserror);
+	if (dbus_error_is_set (&buserror))
+	{
+		g_set_error (error,
+		             GS_LISTENER_ERROR,
+		             GS_LISTENER_ERROR_ACQUISITION_FAILURE,
+		             "%s",
+		             buserror.message);
+	}
+	if (acquired == DBUS_REQUEST_NAME_REPLY_EXISTS) {
+	        g_set_error (error,
+	                     GS_LISTENER_ERROR,
+	                     GS_LISTENER_ERROR_ACQUISITION_FAILURE,
+	                     "%s",
+	                     _("screensaver already running in this session"));
+	        return FALSE;
+        }
+
+	dbus_error_free (&buserror);
+
+	dbus_connection_add_filter (listener->priv->connection, listener_dbus_filter_function, listener, NULL);
+
+	dbus_bus_add_match (listener->priv->connection,
+	                    "type='signal'"
+	                    ",interface='"DBUS_INTERFACE_DBUS"'"
+	                    ",sender='"DBUS_SERVICE_DBUS"'"
+	                    ",member='NameOwnerChanged'",
+	                    NULL);
+
+	if (listener->priv->system_connection != NULL)
+	{
+		dbus_connection_add_filter (listener->priv->system_connection,
+		                            listener_dbus_system_filter_function,
+		                            listener,
+		                            NULL);
+#ifdef WITH_SYSTEMD
+		if (listener->priv->have_systemd) {
+			dbus_bus_add_match (listener->priv->system_connection,
+					    "type='signal'"
+					    ",sender='"SYSTEMD_LOGIND_SERVICE"'"
+					    ",interface='"SYSTEMD_LOGIND_SESSION_INTERFACE"'"
+					    ",member='Unlock'",
+					    NULL);
+			dbus_bus_add_match (listener->priv->system_connection,
+					    "type='signal'"
+					    ",sender='"SYSTEMD_LOGIND_SERVICE"'"
+					    ",interface='"SYSTEMD_LOGIND_SESSION_INTERFACE"'"
+					    ",member='Lock'",
+					    NULL);
+			dbus_bus_add_match (listener->priv->system_connection,
+					    "type='signal'"
+					    ",sender='"SYSTEMD_LOGIND_SERVICE"'"
+					    ",interface='"SYSTEMD_LOGIND_INTERFACE"'"
+					    ",member='PrepareForSleep'",
+					    NULL);
+			listener->priv->logind_inhibit_lock = take_logind_inhibit_lock (listener->priv->system_connection);
+			dbus_bus_add_match (listener->priv->system_connection,
+					    "type='signal'"
+					    ",sender='"SYSTEMD_LOGIND_SERVICE"'"
+					    ",interface='"DBUS_INTERFACE_PROPERTIES"'"
+					    ",member='PropertiesChanged'",
+					    NULL);
+
+			return (acquired != -1);
+		}
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+		dbus_bus_add_match (listener->priv->system_connection,
+		                    "type='signal'"
+		                    ",interface='"CK_SESSION_INTERFACE"'"
+		                    ",member='Unlock'",
+		                    NULL);
+		dbus_bus_add_match (listener->priv->system_connection,
+		                    "type='signal'"
+		                    ",interface='"CK_SESSION_INTERFACE"'"
+		                    ",member='Lock'",
+		                    NULL);
+		dbus_bus_add_match (listener->priv->system_connection,
+		                    "type='signal'"
+		                    ",interface='"CK_SESSION_INTERFACE"'"
+		                    ",member='ActiveChanged'",
+		                    NULL);
+#endif
+	}
+
+	return (acquired != -1);
+}
+
+static char *
+query_session_id (GSListener *listener)
+{
+	DBusMessage    *message;
+	DBusMessage    *reply;
+	DBusError       error;
+	DBusMessageIter reply_iter;
+	char           *ssid;
+
+	if (listener->priv->system_connection == NULL)
+	{
+		gs_debug ("No connection to the system bus");
+		return NULL;
+	}
+
+	ssid = NULL;
+
+	dbus_error_init (&error);
+
+#ifdef WITH_SYSTEMD
+	if (listener->priv->have_systemd) {
+		dbus_uint32_t pid = getpid();
+
+		message = dbus_message_new_method_call (SYSTEMD_LOGIND_SERVICE,
+		                                        SYSTEMD_LOGIND_PATH,
+							SYSTEMD_LOGIND_INTERFACE,
+							"GetSessionByPID");
+		if (message == NULL)
+		{
+			gs_debug ("Couldn't allocate the dbus message");
+			return NULL;
+		}
+
+		if (dbus_message_append_args (message,
+					      DBUS_TYPE_UINT32,
+					      &pid, DBUS_TYPE_INVALID) == FALSE)
+		{
+			gs_debug ("Couldn't add args to the dbus message");
+			return NULL;
+		}
+
+		/* FIXME: use async? */
+		reply = dbus_connection_send_with_reply_and_block (listener->priv->system_connection,
+			message,
+			-1, &error);
+		dbus_message_unref (message);
+
+		if (dbus_error_is_set (&error))
+		{
+			gs_debug ("%s raised:\n %s\n\n", error.name, error.message);
+			dbus_error_free (&error);
+			return NULL;
+		}
+
+		dbus_message_iter_init (reply, &reply_iter);
+		dbus_message_iter_get_basic (&reply_iter, &ssid);
+
+		dbus_message_unref (reply);
+
+		return g_strdup (ssid);
+	}
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+	message = dbus_message_new_method_call (CK_NAME, CK_MANAGER_PATH, CK_MANAGER_INTERFACE, "GetCurrentSession");
+	if (message == NULL)
+	{
+		gs_debug ("Couldn't allocate the dbus message");
+		return NULL;
+	}
+
+	/* FIXME: use async? */
+	reply = dbus_connection_send_with_reply_and_block (listener->priv->system_connection,
+	        message,
+	        -1, &error);
+	dbus_message_unref (message);
+
+	if (dbus_error_is_set (&error))
+	{
+		gs_debug ("%s raised:\n %s\n\n", error.name, error.message);
+		dbus_error_free (&error);
+		return NULL;
+	}
+
+	dbus_message_iter_init (reply, &reply_iter);
+	dbus_message_iter_get_basic (&reply_iter, &ssid);
+
+	dbus_message_unref (reply);
+
+	return g_strdup (ssid);
+#else
+	return NULL;
+#endif
+}
+
+static void
+init_session_id (GSListener *listener)
+{
+	g_free (listener->priv->session_id);
+	listener->priv->session_id = query_session_id (listener);
+	gs_debug ("Got session-id: %s", listener->priv->session_id);
+}
+
+static void
+gs_listener_init (GSListener *listener)
+{
+	listener->priv = gs_listener_get_instance_private (listener);
+
+#ifdef WITH_SYSTEMD
+	/* check if logind is running */
+        listener->priv->have_systemd = (access("/run/systemd/seats/", F_OK) >= 0);
+#endif
+
+	gs_listener_dbus_init (listener);
+
+	init_session_id (listener);
+
+	listener->priv->inhibitors = g_hash_table_new_full (g_int_hash,
+	                             g_int_equal,
+	                             NULL,
+	                             (GDestroyNotify)gs_listener_ref_entry_free);
+	listener->priv->throttlers = g_hash_table_new_full (g_int_hash,
+	                             g_int_equal,
+	                             NULL,
+	                             (GDestroyNotify)gs_listener_ref_entry_free);
+}
+
+static void
+gs_listener_finalize (GObject *object)
+{
+	GSListener *listener;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GS_IS_LISTENER (object));
+
+	listener = GS_LISTENER (object);
+
+	g_return_if_fail (listener->priv != NULL);
+
+	if (listener->priv->inhibitors)
+	{
+		g_hash_table_destroy (listener->priv->inhibitors);
+	}
+
+	if (listener->priv->throttlers)
+	{
+		g_hash_table_destroy (listener->priv->throttlers);
+	}
+
+	g_free (listener->priv->session_id);
+
+	G_OBJECT_CLASS (gs_listener_parent_class)->finalize (object);
+}
+
+GSListener *
+gs_listener_new (void)
+{
+	GSListener *listener;
+
+	listener = g_object_new (GS_TYPE_LISTENER, NULL);
+
+	return GS_LISTENER (listener);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/12.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/12.html new file mode 100644 index 0000000..fbc5481 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/12.html @@ -0,0 +1,5021 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkx.h>
+#include <gio/gio.h>
+
+#define MATE_DESKTOP_USE_UNSTABLE_API
+#include <libmate-desktop/mate-desktop-utils.h>
+
+#ifdef WITH_KBD_LAYOUT_INDICATOR
+#include <libmatekbd/matekbd-indicator.h>
+#endif
+
+#ifdef WITH_LIBNOTIFY
+#include <libnotify/notify.h>
+#endif
+
+#include "gs-lock-plug.h"
+
+#include "gs-debug.h"
+
+#define GSETTINGS_SCHEMA "org.mate.screensaver"
+
+#define KEY_LOCK_DIALOG_THEME "lock-dialog-theme"
+
+#define KEY_LOCK_DIALOG_T_FMT "lock-dialog-time-format"
+#define KEY_LOCK_DIALOG_D_FMT "lock-dialog-date-format"
+
+#define MDM_FLEXISERVER_COMMAND "mdmflexiserver"
+#define MDM_FLEXISERVER_ARGS    "--startnew Standard"
+
+#define GDM_FLEXISERVER_COMMAND "gdmflexiserver"
+#define GDM_FLEXISERVER_ARGS    "--startnew Standard"
+
+/* same as SMS ;) */
+#define NOTE_BUFFER_MAX_CHARS 160
+
+enum
+{
+    AUTH_PAGE = 0,
+};
+
+#define FACE_ICON_SIZE 48
+#define DIALOG_TIMEOUT_MSEC 60000
+
+static void gs_lock_plug_finalize   (GObject         *object);
+
+struct GSLockPlugPrivate
+{
+	GtkWidget   *vbox;
+	GtkWidget   *auth_action_area;
+
+	GtkWidget   *notebook;
+	GtkWidget   *auth_face_image;
+	GtkWidget   *auth_time_label;
+	GtkWidget   *auth_date_label;
+	GtkWidget   *auth_realname_label;
+	GtkWidget   *auth_username_label;
+	GtkWidget   *auth_prompt_label;
+	GtkWidget   *auth_prompt_entry;
+	GtkWidget   *auth_prompt_box;
+	GtkWidget   *auth_capslock_label;
+	GtkWidget   *auth_message_label;
+	GtkWidget   *status_message_label;
+
+	GtkWidget   *auth_unlock_button;
+	GtkWidget   *auth_switch_button;
+	GtkWidget   *auth_cancel_button;
+	GtkWidget   *auth_logout_button;
+	GtkWidget   *auth_note_button;
+	GtkWidget   *note_tab;
+	GtkWidget   *note_tab_label;
+	GtkWidget   *note_text_view;
+	GtkWidget   *note_ok_button;
+	GtkWidget   *note_cancel_button;
+
+	GtkWidget   *auth_prompt_kbd_layout_indicator;
+
+	gboolean     caps_lock_on;
+	gboolean     switch_enabled;
+	gboolean     leave_note_enabled;
+	gboolean     logout_enabled;
+	char        *logout_command;
+	char        *status_message;
+
+	guint        timeout;
+
+	guint        datetime_timeout_id;
+	guint        cancel_timeout_id;
+	guint        auth_check_idle_id;
+	guint        response_idle_id;
+
+	GList       *key_events;
+};
+
+typedef struct _ResponseData ResponseData;
+
+struct _ResponseData
+{
+	gint response_id;
+};
+
+enum
+{
+    RESPONSE,
+    CLOSE,
+    LAST_SIGNAL
+};
+
+enum
+{
+    PROP_0,
+    PROP_LOGOUT_ENABLED,
+    PROP_LOGOUT_COMMAND,
+    PROP_SWITCH_ENABLED,
+    PROP_STATUS_MESSAGE
+};
+
+static guint lock_plug_signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSLockPlug, gs_lock_plug, GTK_TYPE_PLUG)
+
+static void
+gs_lock_plug_style_set (GtkWidget *widget,
+                        GtkStyle  *previous_style)
+{
+	GSLockPlug *plug;
+
+	if (GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->style_set)
+	{
+		GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->style_set (widget, previous_style);
+	}
+
+	plug = GS_LOCK_PLUG (widget);
+
+	if (! plug->priv->vbox)
+	{
+		return;
+	}
+
+	gtk_container_set_border_width (GTK_CONTAINER (plug->priv->vbox), 12);
+	gtk_box_set_spacing (GTK_BOX (plug->priv->vbox), 12);
+
+	gtk_container_set_border_width (GTK_CONTAINER (plug->priv->auth_action_area), 0);
+	gtk_box_set_spacing (GTK_BOX (plug->priv->auth_action_area), 5);
+}
+
+static gboolean
+process_is_running (const char * name)
+{
+        int num_processes;
+        gchar *command = g_strdup_printf ("pidof %s | wc -l", name);
+        FILE *fp = popen(command, "r");
+
+        if (fscanf(fp, "%d", &num_processes) != 1)
+                num_processes = 0;
+
+        pclose(fp);
+        g_free (command);
+
+        if (num_processes > 0) {
+                return TRUE;
+        } else {
+                return FALSE;
+        }
+}
+
+static void
+do_user_switch (GSLockPlug *plug)
+{
+	GError  *error;
+	gboolean res;
+	char    *command;
+
+	if (process_is_running ("mdm"))
+	{
+		/* MDM */
+		command = g_strdup_printf ("%s %s",
+								   MDM_FLEXISERVER_COMMAND,
+								   MDM_FLEXISERVER_ARGS);
+
+		error = NULL;
+		res = mate_gdk_spawn_command_line_on_screen (gdk_screen_get_default (),
+												command,
+												&error);
+
+		g_free (command);
+
+		if (! res)
+		{
+			gs_debug ("Unable to start MDM greeter: %s", error->message);
+			g_error_free (error);
+		}
+	}
+	else if (process_is_running ("gdm") || process_is_running("gdm3") || process_is_running("gdm-binary"))
+	{
+		/* GDM */
+		command = g_strdup_printf ("%s %s",
+								   GDM_FLEXISERVER_COMMAND,
+								   GDM_FLEXISERVER_ARGS);
+
+		error = NULL;
+		res = mate_gdk_spawn_command_line_on_screen (gdk_screen_get_default (),
+												command,
+												&error);
+
+		g_free (command);
+
+		if (! res) {
+			gs_debug ("Unable to start GDM greeter: %s", error->message);
+			g_error_free (error);
+		}
+	}
+	else if (g_getenv ("XDG_SEAT_PATH") != NULL)
+	{
+		/* LightDM */
+		GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
+		GDBusProxy *proxy = NULL;
+
+		error = NULL;
+		proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+											  flags,
+											  NULL,
+											  "org.freedesktop.DisplayManager",
+											  g_getenv ("XDG_SEAT_PATH"),
+											  "org.freedesktop.DisplayManager.Seat",
+											  NULL,
+											  &error);
+		if (proxy != NULL) {
+			g_dbus_proxy_call_sync (proxy,
+									"SwitchToGreeter",
+									g_variant_new ("()"),
+									G_DBUS_CALL_FLAGS_NONE,
+									-1,
+									NULL,
+									NULL);
+			g_object_unref (proxy);
+		}
+		else {
+			gs_debug ("Unable to start LightDM greeter: %s", error->message);
+			g_error_free (error);
+		}
+	}
+
+}
+
+static void
+set_status_text (GSLockPlug *plug,
+                 const char *text)
+{
+	if (plug->priv->auth_message_label != NULL)
+	{
+		gtk_label_set_text (GTK_LABEL (plug->priv->auth_message_label), text);
+	}
+}
+
+static void
+date_time_update (GSLockPlug *plug)
+{
+	GDateTime *datetime;
+	gchar *time;
+	gchar *date;
+	gchar *tfmt;
+	gchar *dfmt;
+
+	gchar *str;
+
+	GSettings *settings;
+
+	settings = g_settings_new (GSETTINGS_SCHEMA);
+	tfmt = g_settings_get_string (settings, KEY_LOCK_DIALOG_T_FMT);
+	dfmt = g_settings_get_string (settings, KEY_LOCK_DIALOG_D_FMT);
+	g_object_unref (settings);
+
+	/* Time/Date formating https://developer.gnome.org/glib/stable/glib-GDateTime.html#g-date-time-format */
+
+	datetime = g_date_time_new_now_local ();
+	if (g_strcmp0(tfmt, "locale") == 0)
+	{
+		// Use locale default format
+		time = g_date_time_format (datetime, "%X");
+	}
+	else
+	{
+		// Apply user defined format
+		time = g_date_time_format (datetime, tfmt);
+	}
+
+	if (g_strcmp0(dfmt, "locale") == 0)
+	{
+		// Use locale default format
+		date = g_date_time_format (datetime, _("%A, %B %e"));
+	}
+	else
+	{
+		// Apply user defined format
+		date = g_date_time_format (datetime, dfmt);
+	}
+
+	str = g_strdup_printf ("<span size=\"xx-large\" weight=\"ultrabold\">%s</span>", time);
+	gtk_label_set_text (GTK_LABEL (plug->priv->auth_time_label), str);
+	gtk_label_set_use_markup (GTK_LABEL (plug->priv->auth_time_label), TRUE);
+	g_free (str);
+
+	str = g_strdup_printf ("<span size=\"large\">%s</span>", date);
+	gtk_label_set_markup (GTK_LABEL (plug->priv->auth_date_label), str);
+	gtk_label_set_use_markup (GTK_LABEL (plug->priv->auth_date_label), TRUE);
+	g_free (str);
+
+	g_free (time);
+	g_free (date);
+	g_free (tfmt);
+	g_free (dfmt);
+	g_date_time_unref (datetime);
+}
+
+void
+gs_lock_plug_set_sensitive (GSLockPlug *plug,
+                            gboolean    sensitive)
+{
+	g_return_if_fail (GS_IS_LOCK_PLUG (plug));
+
+	gtk_widget_set_sensitive (plug->priv->auth_prompt_entry, sensitive);
+	gtk_widget_set_sensitive (plug->priv->auth_action_area, sensitive);
+}
+
+static void
+remove_datetime_timeout (GSLockPlug *plug)
+{
+	if (plug->priv->datetime_timeout_id > 0)
+	{
+		g_source_remove (plug->priv->datetime_timeout_id);
+		plug->priv->datetime_timeout_id = 0;
+	}
+}
+
+static void
+remove_cancel_timeout (GSLockPlug *plug)
+{
+	if (plug->priv->cancel_timeout_id > 0)
+	{
+		g_source_remove (plug->priv->cancel_timeout_id);
+		plug->priv->cancel_timeout_id = 0;
+	}
+}
+
+static void
+remove_response_idle (GSLockPlug *plug)
+{
+	if (plug->priv->response_idle_id > 0)
+	{
+		g_source_remove (plug->priv->response_idle_id);
+		plug->priv->response_idle_id = 0;
+	}
+}
+
+static void
+gs_lock_plug_response (GSLockPlug *plug,
+                       gint        response_id)
+{
+	int new_response;
+
+	new_response = response_id;
+
+	g_return_if_fail (GS_IS_LOCK_PLUG (plug));
+
+	/* Act only on response IDs we recognize */
+	if (!(response_id == GS_LOCK_PLUG_RESPONSE_OK
+	        || response_id == GS_LOCK_PLUG_RESPONSE_CANCEL))
+	{
+		return;
+	}
+
+	remove_cancel_timeout (plug);
+	remove_response_idle (plug);
+
+	if (response_id == GS_LOCK_PLUG_RESPONSE_CANCEL)
+	{
+		gtk_entry_set_text (GTK_ENTRY (plug->priv->auth_prompt_entry), "");
+	}
+
+	g_signal_emit (plug,
+	               lock_plug_signals [RESPONSE],
+	               0,
+	               new_response);
+}
+
+static gboolean
+response_cancel_idle_cb (gpointer user_data)
+{
+	GSLockPlug *plug = user_data;
+
+	plug->priv->response_idle_id = 0;
+
+	gs_lock_plug_response (plug, GS_LOCK_PLUG_RESPONSE_CANCEL);
+
+	return FALSE;
+}
+
+static gboolean
+dialog_timed_out (gpointer user_data)
+{
+	GSLockPlug *plug = user_data;
+
+	gs_lock_plug_set_sensitive (plug, FALSE);
+	set_status_text (plug, _("Time has expired."));
+
+	if (plug->priv->response_idle_id != 0)
+	{
+		g_warning ("Response idle ID already set but shouldn't be");
+	}
+
+	remove_response_idle (plug);
+
+	plug->priv->response_idle_id = g_timeout_add (2000,
+	                                              response_cancel_idle_cb,
+	                                              plug);
+	return FALSE;
+}
+
+static void
+capslock_update (GSLockPlug *plug,
+                 gboolean    is_on)
+{
+
+	plug->priv->caps_lock_on = is_on;
+
+	if (plug->priv->auth_capslock_label == NULL)
+	{
+		return;
+	}
+
+	if (is_on)
+	{
+		gtk_label_set_text (GTK_LABEL (plug->priv->auth_capslock_label),
+		                    _("You have the Caps Lock key on."));
+	}
+	else
+	{
+		gtk_label_set_text (GTK_LABEL (plug->priv->auth_capslock_label),
+		                    "");
+	}
+}
+
+static gboolean
+is_capslock_on (void)
+{
+	GdkKeymap *keymap;
+	gboolean res;
+
+	res = FALSE;
+
+	keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	if (keymap != NULL) {
+		res = gdk_keymap_get_caps_lock_state (keymap);
+	}
+
+	return res;
+}
+
+static void
+restart_cancel_timeout (GSLockPlug *plug)
+{
+	remove_cancel_timeout (plug);
+
+	plug->priv->cancel_timeout_id = g_timeout_add (plug->priv->timeout,
+	                                               dialog_timed_out,
+	                                               plug);
+}
+
+void
+gs_lock_plug_get_text (GSLockPlug *plug,
+                       char      **text)
+{
+	const char *typed_text;
+	char       *null_text;
+	char       *local_text;
+
+	typed_text = gtk_entry_get_text (GTK_ENTRY (plug->priv->auth_prompt_entry));
+	local_text = g_locale_from_utf8 (typed_text, strlen (typed_text), NULL, NULL, NULL);
+
+	null_text = g_strnfill (strlen (typed_text) + 1, '\b');
+	gtk_entry_set_text (GTK_ENTRY (plug->priv->auth_prompt_entry), null_text);
+	gtk_entry_set_text (GTK_ENTRY (plug->priv->auth_prompt_entry), "");
+	g_free (null_text);
+
+	if (text != NULL)
+	{
+		*text = local_text;
+	}
+	else
+	{
+		g_free (local_text);
+	}
+}
+
+typedef struct
+{
+	GSLockPlug *plug;
+	gint response_id;
+	GMainLoop *loop;
+	gboolean destroyed;
+} RunInfo;
+
+static void
+shutdown_loop (RunInfo *ri)
+{
+	if (g_main_loop_is_running (ri->loop))
+		g_main_loop_quit (ri->loop);
+}
+
+static void
+run_unmap_handler (GSLockPlug *plug,
+                   gpointer data)
+{
+	RunInfo *ri = data;
+
+	shutdown_loop (ri);
+}
+
+static void
+run_response_handler (GSLockPlug *plug,
+                      gint response_id,
+                      gpointer data)
+{
+	RunInfo *ri;
+
+	ri = data;
+
+	ri->response_id = response_id;
+
+	shutdown_loop (ri);
+}
+
+static gint
+run_delete_handler (GSLockPlug *plug,
+                    GdkEventAny *event,
+                    gpointer data)
+{
+	RunInfo *ri = data;
+
+	shutdown_loop (ri);
+
+	return TRUE; /* Do not destroy */
+}
+
+static void
+run_destroy_handler (GSLockPlug *plug,
+                     gpointer data)
+{
+	RunInfo *ri = data;
+
+	/* shutdown_loop will be called by run_unmap_handler */
+	ri->destroyed = TRUE;
+}
+
+static void
+run_keymap_handler (GdkKeymap *keymap,
+                    GSLockPlug *plug)
+{
+	capslock_update (plug, is_capslock_on ());
+}
+
+/* adapted from GTK+ gtkdialog.c */
+int
+gs_lock_plug_run (GSLockPlug *plug)
+{
+	RunInfo ri = { NULL, GTK_RESPONSE_NONE, NULL, FALSE };
+	gboolean was_modal;
+	gulong response_handler;
+	gulong unmap_handler;
+	gulong destroy_handler;
+	gulong delete_handler;<--- Shadow variable
+	gulong keymap_handler;
+	GdkKeymap *keymap;
+
+	g_return_val_if_fail (GS_IS_LOCK_PLUG (plug), -1);
+
+	g_object_ref (plug);
+
+	was_modal = gtk_window_get_modal (GTK_WINDOW (plug));
+	if (!was_modal)
+	{
+		gtk_window_set_modal (GTK_WINDOW (plug), TRUE);
+	}
+
+	if (!gtk_widget_get_visible (GTK_WIDGET (plug)))
+	{
+		gtk_widget_show (GTK_WIDGET (plug));
+	}
+
+	keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (plug)));
+
+	keymap_handler =
+	    g_signal_connect (keymap,
+	                      "state-changed",
+	                      G_CALLBACK (run_keymap_handler),
+	                      plug);
+
+	response_handler =
+	    g_signal_connect (plug,
+	                      "response",
+	                      G_CALLBACK (run_response_handler),
+	                      &ri);
+
+	unmap_handler =
+	    g_signal_connect (plug,
+	                      "unmap",
+	                      G_CALLBACK (run_unmap_handler),
+	                      &ri);
+
+	delete_handler =
+	    g_signal_connect (plug,
+	                      "delete_event",
+	                      G_CALLBACK (run_delete_handler),
+	                      &ri);
+
+	destroy_handler =
+	    g_signal_connect (plug,
+	                      "destroy",
+	                      G_CALLBACK (run_destroy_handler),
+	                      &ri);
+
+	ri.loop = g_main_loop_new (NULL, FALSE);
+
+	g_main_loop_run (ri.loop);
+
+	g_main_loop_unref (ri.loop);
+
+	ri.loop = NULL;
+
+	if (!ri.destroyed)
+	{
+		if (! was_modal)
+		{
+			gtk_window_set_modal (GTK_WINDOW (plug), FALSE);
+		}
+
+		g_signal_handler_disconnect (plug, response_handler);
+		g_signal_handler_disconnect (plug, unmap_handler);
+		g_signal_handler_disconnect (plug, delete_handler);
+		g_signal_handler_disconnect (plug, destroy_handler);
+		g_signal_handler_disconnect (keymap, keymap_handler);
+	}
+
+	g_object_unref (plug);
+
+	return ri.response_id;
+}
+
+static cairo_surface_t *
+surface_from_pixbuf (GdkPixbuf *pixbuf)
+{
+	cairo_surface_t *surface;
+	cairo_t         *cr;
+
+	surface = cairo_image_surface_create (gdk_pixbuf_get_has_alpha (pixbuf) ?
+	                                      CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
+	                                      gdk_pixbuf_get_width (pixbuf),
+	                                      gdk_pixbuf_get_height (pixbuf));
+	cr = cairo_create (surface);
+	gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+	cairo_paint (cr);
+	cairo_destroy (cr);
+
+	return surface;
+}
+
+static void
+rounded_rectangle (cairo_t *cr,
+                   gdouble  aspect,
+                   gdouble  x,
+                   gdouble  y,
+                   gdouble  corner_radius,
+                   gdouble  width,
+                   gdouble  height)
+{
+	gdouble radius;
+	gdouble degrees;
+
+	radius = corner_radius / aspect;
+	degrees = G_PI / 180.0;
+
+	cairo_new_sub_path (cr);
+	cairo_arc (cr,
+	           x + width - radius,
+	           y + radius,
+	           radius,
+	           -90 * degrees,
+	           0 * degrees);
+	cairo_arc (cr,
+	           x + width - radius,
+	           y + height - radius,
+	           radius,
+	           0 * degrees,
+	           90 * degrees);
+	cairo_arc (cr,
+	           x + radius,
+	           y + height - radius,
+	           radius,
+	           90 * degrees,
+	           180 * degrees);
+	cairo_arc (cr,
+	           x + radius,
+	           y + radius,
+	           radius,
+	           180 * degrees,
+	           270 * degrees);
+	cairo_close_path (cr);
+}
+
+/* copied from gnome-screensaver 3.x */
+
+/**
+ * go_cairo_convert_data_to_pixbuf:
+ * @src: a pointer to pixel data in cairo format
+ * @dst: a pointer to pixel data in pixbuf format
+ * @width: image width
+ * @height: image height
+ * @rowstride: data rowstride
+ *
+ * Converts the pixel data stored in @src in CAIRO_FORMAT_ARGB32 cairo format
+ * to GDK_COLORSPACE_RGB pixbuf format and move them
+ * to @dst. If @src == @dst, pixel are converted in place.
+ **/
+
+static void
+go_cairo_convert_data_to_pixbuf (unsigned char *dst,
+                                 unsigned char const *src,
+                                 int width,
+                                 int height,
+                                 int rowstride)
+{
+	int i,j;
+	unsigned int t;
+	unsigned char a, b, c;
+
+	g_return_if_fail (dst != NULL);
+
+#define MULT(d,c,a,t) G_STMT_START { t = (a)? c * 255 / a: 0; d = t;} G_STMT_END
+
+	if (src == dst || src == NULL) {
+		for (i = 0; i < height; i++) {
+			for (j = 0; j < width; j++) {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+				MULT(a, dst[2], dst[3], t);
+				MULT(b, dst[1], dst[3], t);
+				MULT(c, dst[0], dst[3], t);
+				dst[0] = a;
+				dst[1] = b;
+				dst[2] = c;
+#else
+				MULT(a, dst[1], dst[0], t);
+				MULT(b, dst[2], dst[0], t);
+				MULT(c, dst[3], dst[0], t);
+				dst[3] = dst[0];
+				dst[0] = a;
+				dst[1] = b;
+				dst[2] = c;
+#endif
+					dst += 4;
+			}
+			dst += rowstride - width * 4;
+		}
+	} else {
+		for (i = 0; i < height; i++) {
+			for (j = 0; j < width; j++) {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+				MULT(dst[0], src[2], src[3], t);
+				MULT(dst[1], src[1], src[3], t);
+				MULT(dst[2], src[0], src[3], t);
+				dst[3] = src[3];
+#else
+				MULT(dst[0], src[1], src[0], t);
+				MULT(dst[1], src[2], src[0], t);
+				MULT(dst[2], src[3], src[0], t);
+				dst[3] = src[0];
+#endif
+				src += 4;
+				dst += 4;
+			}
+			src += rowstride - width * 4;
+			dst += rowstride - width * 4;
+		}
+	}
+#undef MULT
+}
+
+static void
+cairo_to_pixbuf (guint8    *src_data,
+                 GdkPixbuf *dst_pixbuf)
+{
+	unsigned char *src;
+	unsigned char *dst;
+	guint          w;
+	guint          h;
+	guint          rowstride;
+
+	w = gdk_pixbuf_get_width (dst_pixbuf);
+	h = gdk_pixbuf_get_height (dst_pixbuf);
+	rowstride = gdk_pixbuf_get_rowstride (dst_pixbuf);
+
+	dst = gdk_pixbuf_get_pixels (dst_pixbuf);
+	src = src_data;
+
+	go_cairo_convert_data_to_pixbuf (dst, src, w, h, rowstride);
+}
+
+static GdkPixbuf *
+frame_pixbuf (GdkPixbuf *source)
+{
+	GdkPixbuf       *dest;
+	cairo_t         *cr;
+	cairo_surface_t *surface;
+	guint            w;
+	guint            h;
+	guint            rowstride;
+	int              frame_width;
+	double           radius;
+	guint8          *data;
+
+	frame_width = 5;
+
+	w = gdk_pixbuf_get_width (source) + frame_width * 2;
+	h = gdk_pixbuf_get_height (source) + frame_width * 2;
+	radius = w / 10;
+
+	dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+						   TRUE,
+						   8,
+						   w,
+						   h);
+	rowstride = gdk_pixbuf_get_rowstride (dest);
+
+	data = g_new0 (guint8, h * rowstride);
+
+	surface = cairo_image_surface_create_for_data (data,
+												   CAIRO_FORMAT_ARGB32,
+												   w,
+												   h,
+												   rowstride);
+	cr = cairo_create (surface);
+	cairo_surface_destroy (surface);
+
+	/* set up image */
+	cairo_rectangle (cr, 0, 0, w, h);
+	cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
+	cairo_fill (cr);
+
+	rounded_rectangle (cr,
+					   1.0,
+					   frame_width + 0.5,
+					   frame_width + 0.5,
+					   radius,
+					   w - frame_width * 2 - 1,
+					   h - frame_width * 2 - 1);
+	cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3);
+	cairo_fill_preserve (cr);
+
+	surface = surface_from_pixbuf (source);
+	cairo_set_source_surface (cr, surface, frame_width, frame_width);
+	cairo_fill (cr);
+	cairo_surface_destroy (surface);
+
+	cairo_to_pixbuf (data, dest);
+
+	cairo_destroy (cr);
+	g_free (data);
+
+	return dest;
+}
+
+/* end copied from gdm-user.c */
+
+static void
+image_set_from_pixbuf (GtkImage  *image,
+                       GdkPixbuf *source)
+{
+	GdkPixbuf *pixbuf;
+
+	pixbuf = frame_pixbuf (source);
+	gtk_image_set_from_pixbuf (image, pixbuf);
+	g_object_unref (pixbuf);
+}
+
+static gboolean
+check_user_file (const gchar *filename,
+                 uid_t        user,
+                 gssize       max_file_size,
+                 gboolean     relax_group,
+                 gboolean     relax_other)
+{
+	struct stat fileinfo;
+
+	if (max_file_size < 0)
+	{
+		max_file_size = G_MAXSIZE;
+	}
+
+	/* Exists/Readable? */
+	if (g_stat (filename, &fileinfo) < 0)
+	{
+		return FALSE;
+	}
+
+	/* Is a regular file */
+	if (G_UNLIKELY (!S_ISREG (fileinfo.st_mode)))
+	{
+		return FALSE;
+	}
+
+	/* Owned by user? */
+	if (G_UNLIKELY (fileinfo.st_uid != user))
+	{
+		return FALSE;
+	}
+
+	/* Group not writable or relax_group? */
+	if (G_UNLIKELY ((fileinfo.st_mode & S_IWGRP) == S_IWGRP && !relax_group))
+	{
+		return FALSE;
+	}
+
+	/* Other not writable or relax_other? */
+	if (G_UNLIKELY ((fileinfo.st_mode & S_IWOTH) == S_IWOTH && !relax_other))
+	{
+		return FALSE;
+	}
+
+	/* Size is kosher? */
+	if (G_UNLIKELY (fileinfo.st_size > max_file_size))
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+set_face_image (GSLockPlug *plug)
+{
+	GdkPixbuf    *pixbuf;
+	const char   *homedir;
+	char         *path;
+	int           icon_size = 96;
+	gsize         user_max_file = 65536;
+	uid_t         uid;
+
+	homedir = g_get_home_dir ();
+	uid = getuid ();
+
+	path = g_build_filename (homedir, ".face", NULL);
+
+	pixbuf = NULL;
+	if (check_user_file (path, uid, user_max_file, 0, 0))
+	{
+		pixbuf = gdk_pixbuf_new_from_file_at_size (path,
+		         icon_size,
+		         icon_size,
+		         NULL);
+	}
+
+	g_free (path);
+
+	if (pixbuf == NULL)
+	{
+		return FALSE;
+	}
+
+	image_set_from_pixbuf (GTK_IMAGE (plug->priv->auth_face_image), pixbuf);
+
+	g_object_unref (pixbuf);
+
+	return TRUE;
+}
+
+#if !GTK_CHECK_VERSION (3, 23, 0)
+static void
+gs_lock_plug_get_preferred_width (GtkWidget *widget, gint *minimum_width, gint *natural_width)
+{
+    gint scale;
+
+    GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->get_preferred_width (widget, minimum_width, natural_width);
+
+    scale = gtk_widget_get_scale_factor (widget);
+    *minimum_width /= scale;
+    *natural_width /= scale;
+}
+
+static void
+gs_lock_plug_get_preferred_height_for_width (GtkWidget *widget, gint width, gint *minimum_height, gint *natural_height)
+{
+    gint scale;
+
+    GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->get_preferred_height_for_width (widget, width, minimum_height, natural_height);
+
+    scale = gtk_widget_get_scale_factor (widget);
+    *minimum_height /= scale;
+    *natural_height /= scale;
+}
+#endif
+
+static void
+gs_lock_plug_show (GtkWidget *widget)
+{
+	GSLockPlug *plug = GS_LOCK_PLUG (widget);
+
+	gs_profile_start (NULL);
+
+	gs_profile_start ("parent");
+	if (GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->show)
+	{
+		GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->show (widget);
+	}
+
+	gs_profile_end ("parent");
+
+	if (plug->priv->auth_face_image)
+	{
+		set_face_image (plug);
+	}
+
+	capslock_update (plug, is_capslock_on ());
+
+	restart_cancel_timeout (plug);
+
+	gs_profile_end (NULL);
+}
+
+static void
+gs_lock_plug_hide (GtkWidget *widget)
+{
+	if (GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->hide)
+	{
+		GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->hide (widget);
+	}
+}
+
+static void
+queue_key_event (GSLockPlug  *plug,
+                 GdkEventKey *event)
+{
+	GdkEvent *saved_event;
+
+	saved_event = gdk_event_copy ((GdkEvent *)event);
+	plug->priv->key_events = g_list_prepend (plug->priv->key_events,
+	                         saved_event);
+}
+
+static void
+forward_key_events (GSLockPlug *plug)
+{
+	plug->priv->key_events = g_list_reverse (plug->priv->key_events);
+	while (plug->priv->key_events != NULL)
+	{
+		GdkEventKey *event = plug->priv->key_events->data;
+
+		gtk_window_propagate_key_event (GTK_WINDOW (plug), event);
+
+		gdk_event_free ((GdkEvent *)event);
+
+		plug->priv->key_events = g_list_delete_link (plug->priv->key_events,
+		                         plug->priv->key_events);
+	}
+}
+
+static void
+gs_lock_plug_set_logout_enabled (GSLockPlug *plug,
+                                 gboolean    logout_enabled)
+{
+	g_return_if_fail (GS_LOCK_PLUG (plug));
+
+	if (plug->priv->logout_enabled == logout_enabled)
+	{
+		return;
+	}
+
+	plug->priv->logout_enabled = logout_enabled;
+	g_object_notify (G_OBJECT (plug), "logout-enabled");
+
+	if (plug->priv->auth_logout_button == NULL)
+	{
+		return;
+	}
+
+	if (logout_enabled)
+	{
+		gtk_widget_show (plug->priv->auth_logout_button);
+	}
+	else
+	{
+		gtk_widget_hide (plug->priv->auth_logout_button);
+	}
+}
+
+static void
+gs_lock_plug_set_logout_command (GSLockPlug *plug,
+                                 const char *command)
+{
+	g_return_if_fail (GS_LOCK_PLUG (plug));
+
+	g_free (plug->priv->logout_command);
+
+	if (command)
+	{
+		plug->priv->logout_command = g_strdup (command);
+	}
+	else
+	{
+		plug->priv->logout_command = NULL;
+	}
+}
+
+static void
+gs_lock_plug_set_status_message (GSLockPlug *plug,
+                                 const char *status_message)
+{
+	g_return_if_fail (GS_LOCK_PLUG (plug));
+
+	g_free (plug->priv->status_message);
+	plug->priv->status_message = g_strdup (status_message);
+
+	if (plug->priv->status_message_label)
+	{
+		if (plug->priv->status_message)
+		{
+			gtk_label_set_text (GTK_LABEL (plug->priv->status_message_label),
+			                    plug->priv->status_message);
+			gtk_widget_show (plug->priv->status_message_label);
+		}
+		else
+		{
+			gtk_widget_hide (plug->priv->status_message_label);
+		}
+	}
+}
+
+static void
+gs_lock_plug_get_property (GObject    *object,
+                           guint       prop_id,
+                           GValue     *value,
+                           GParamSpec *pspec)
+{
+	GSLockPlug *self;
+
+	self = GS_LOCK_PLUG (object);
+
+	switch (prop_id)
+	{
+	case PROP_LOGOUT_ENABLED:
+		g_value_set_boolean (value, self->priv->logout_enabled);
+		break;
+	case PROP_LOGOUT_COMMAND:
+		g_value_set_string (value, self->priv->logout_command);
+		break;
+	case PROP_SWITCH_ENABLED:
+		g_value_set_boolean (value, self->priv->switch_enabled);
+		break;
+	case PROP_STATUS_MESSAGE:
+		g_value_set_string (value, self->priv->status_message);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gs_lock_plug_set_switch_enabled (GSLockPlug *plug,
+                                 gboolean    switch_enabled)
+{
+	g_return_if_fail (GS_LOCK_PLUG (plug));
+
+	if (plug->priv->switch_enabled == switch_enabled)
+	{
+		return;
+	}
+
+	plug->priv->switch_enabled = switch_enabled;
+	g_object_notify (G_OBJECT (plug), "switch-enabled");
+
+	if (plug->priv->auth_switch_button == NULL)
+	{
+		return;
+	}
+
+	if (switch_enabled)
+	{
+		if (process_is_running ("mdm"))
+		{
+			/* MDM  */
+			gtk_widget_show (plug->priv->auth_switch_button);
+		}
+		else if (process_is_running ("gdm") || process_is_running("gdm3") || process_is_running("gdm-binary"))
+		{
+			/* GDM */
+			gtk_widget_show (plug->priv->auth_switch_button);
+		}
+		else if (g_getenv ("XDG_SEAT_PATH") != NULL)
+		{
+			/* LightDM */
+			gtk_widget_show (plug->priv->auth_switch_button);
+		}
+		else
+		{
+			gs_debug ("Warning: Unknown DM for switch button");
+			gtk_widget_hide (plug->priv->auth_switch_button);
+		}
+	}
+	else
+	{
+		gtk_widget_hide (plug->priv->auth_switch_button);
+	}
+}
+
+static void
+gs_lock_plug_set_property (GObject            *object,
+                           guint               prop_id,
+                           const GValue       *value,
+                           GParamSpec         *pspec)
+{
+	GSLockPlug *self;
+
+	self = GS_LOCK_PLUG (object);
+
+	switch (prop_id)
+	{
+	case PROP_LOGOUT_ENABLED:
+		gs_lock_plug_set_logout_enabled (self, g_value_get_boolean (value));
+		break;
+	case PROP_LOGOUT_COMMAND:
+		gs_lock_plug_set_logout_command (self, g_value_get_string (value));
+		break;
+	case PROP_STATUS_MESSAGE:
+		gs_lock_plug_set_status_message (self, g_value_get_string (value));
+		break;
+	case PROP_SWITCH_ENABLED:
+		gs_lock_plug_set_switch_enabled (self, g_value_get_boolean (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gs_lock_plug_close (GSLockPlug *plug)
+{
+	/* Synthesize delete_event to close dialog. */
+
+	GtkWidget *widget = GTK_WIDGET (plug);
+	GdkEvent  *event;
+
+	event = gdk_event_new (GDK_DELETE);
+	event->any.window = g_object_ref (gtk_widget_get_window(widget));
+	event->any.send_event = TRUE;
+
+	gtk_main_do_event (event);
+	gdk_event_free (event);
+}
+
+static void
+gs_lock_plug_class_init (GSLockPlugClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+	GtkBindingSet  *binding_set;
+
+	object_class->finalize     = gs_lock_plug_finalize;
+	object_class->get_property = gs_lock_plug_get_property;
+	object_class->set_property = gs_lock_plug_set_property;
+
+	widget_class->style_set                      = gs_lock_plug_style_set;
+	widget_class->show                           = gs_lock_plug_show;
+	widget_class->hide                           = gs_lock_plug_hide;
+#if !GTK_CHECK_VERSION (3, 23, 0)
+	widget_class->get_preferred_width            = gs_lock_plug_get_preferred_width;
+	widget_class->get_preferred_height_for_width = gs_lock_plug_get_preferred_height_for_width;
+#endif
+
+	klass->close = gs_lock_plug_close;
+
+	lock_plug_signals [RESPONSE] = g_signal_new ("response",
+	                               G_OBJECT_CLASS_TYPE (klass),
+	                               G_SIGNAL_RUN_LAST,
+	                               G_STRUCT_OFFSET (GSLockPlugClass, response),
+	                               NULL, NULL,
+	                               g_cclosure_marshal_VOID__INT,
+	                               G_TYPE_NONE, 1,
+	                               G_TYPE_INT);
+	lock_plug_signals [CLOSE] = g_signal_new ("close",
+	                            G_OBJECT_CLASS_TYPE (klass),
+	                            G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+	                            G_STRUCT_OFFSET (GSLockPlugClass, close),
+	                            NULL, NULL,
+	                            g_cclosure_marshal_VOID__VOID,
+	                            G_TYPE_NONE, 0);
+
+	g_object_class_install_property (object_class,
+	                                 PROP_LOGOUT_ENABLED,
+	                                 g_param_spec_boolean ("logout-enabled",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LOGOUT_COMMAND,
+	                                 g_param_spec_string ("logout-command",
+	                                         NULL,
+	                                         NULL,
+	                                         NULL,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_STATUS_MESSAGE,
+	                                 g_param_spec_string ("status-message",
+	                                         NULL,
+	                                         NULL,
+	                                         NULL,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_SWITCH_ENABLED,
+	                                 g_param_spec_boolean ("switch-enabled",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+
+	binding_set = gtk_binding_set_by_class (klass);
+
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0,
+	                              "close", 0);
+}
+
+static void
+clear_clipboards (GSLockPlug *plug)
+{
+	GtkClipboard *clipboard;
+
+	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (plug), GDK_SELECTION_PRIMARY);
+	gtk_clipboard_clear (clipboard);
+	gtk_clipboard_set_text (clipboard, "", -1);
+	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (plug), GDK_SELECTION_CLIPBOARD);
+	gtk_clipboard_clear (clipboard);
+	gtk_clipboard_set_text (clipboard, "", -1);
+}
+
+static void
+take_note (GtkButton  *button,
+           GSLockPlug *plug)
+{
+	int page;
+
+	page = gtk_notebook_page_num (GTK_NOTEBOOK (plug->priv->notebook), plug->priv->note_tab);
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (plug->priv->notebook), page);
+	/* this counts as activity so restart the timer */
+	restart_cancel_timeout (plug);
+}
+
+static void
+submit_note (GtkButton  *button,
+             GSLockPlug *plug)
+{
+#ifdef WITH_LIBNOTIFY
+	char               *text;
+	char                summary[128];
+	char               *escaped_text;
+	GtkTextBuffer      *buffer;
+	GtkTextIter         start, end;
+	time_t              t;
+	struct tm          *tmp;
+	NotifyNotification *note;
+
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (plug->priv->notebook), AUTH_PAGE);
+	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (plug->priv->note_text_view));
+	gtk_text_buffer_get_bounds (buffer, &start, &end);
+	text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+	gtk_text_buffer_set_text (buffer, "", 0);
+	escaped_text = g_markup_escape_text (text, -1);
+
+	t = time (NULL);
+	tmp = localtime (&t);
+	strftime (summary, 128, "%X", tmp);
+
+	note = notify_notification_new (summary, escaped_text, NULL);
+	notify_notification_set_timeout (note, NOTIFY_EXPIRES_NEVER);
+	notify_notification_show (note, NULL);
+	g_object_unref (note);
+
+	g_free (text);
+	g_free (escaped_text);
+
+	gs_lock_plug_response (plug, GS_LOCK_PLUG_RESPONSE_CANCEL);
+#endif /* WITH_LIBNOTIFY */
+}
+
+static void
+cancel_note (GtkButton  *button,
+             GSLockPlug *plug)
+{
+	GtkTextBuffer *buffer;
+
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (plug->priv->notebook), AUTH_PAGE);
+	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (plug->priv->note_text_view));
+	gtk_text_buffer_set_text (buffer, "", 0);
+
+	/* this counts as activity so restart the timer */
+	restart_cancel_timeout (plug);
+
+	gtk_window_set_default (GTK_WINDOW (plug), plug->priv->auth_unlock_button);
+
+	clear_clipboards (plug);
+}
+
+static void
+logout_button_clicked (GtkButton  *button,
+                       GSLockPlug *plug)
+{
+	char   **argv  = NULL;
+	GError  *error = NULL;
+	gboolean res;
+
+	if (! plug->priv->logout_command)
+	{
+		return;
+	}
+
+	res = g_shell_parse_argv (plug->priv->logout_command, NULL, &argv, &error);
+
+	if (! res)
+	{
+		g_warning ("Could not parse logout command: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	g_spawn_async (g_get_home_dir (),
+	               argv,
+	               NULL,
+	               G_SPAWN_SEARCH_PATH,
+	               NULL,
+	               NULL,
+	               NULL,
+	               &error);
+
+	g_strfreev (argv);
+
+	if (error)
+	{
+		g_warning ("Could not run logout command: %s", error->message);
+		g_error_free (error);
+	}
+}
+
+void
+gs_lock_plug_set_busy (GSLockPlug *plug)
+{
+	GdkDisplay *display;
+	GdkCursor *cursor;
+	GtkWidget *top_level;
+
+	top_level = gtk_widget_get_toplevel (GTK_WIDGET (plug));
+
+	display = gtk_widget_get_display (GTK_WIDGET (plug));
+	cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
+
+	gdk_window_set_cursor (gtk_widget_get_window (top_level), cursor);
+	g_object_unref (cursor);
+}
+
+void
+gs_lock_plug_set_ready (GSLockPlug *plug)
+{
+	GdkDisplay *display;
+	GdkCursor *cursor;
+	GtkWidget *top_level;
+
+	top_level = gtk_widget_get_toplevel (GTK_WIDGET (plug));
+
+	display = gtk_widget_get_display (GTK_WIDGET (plug));
+	cursor = gdk_cursor_new_for_display (display, GDK_LEFT_PTR);
+	gdk_window_set_cursor (gtk_widget_get_window (top_level), cursor);
+	g_object_unref (cursor);
+}
+
+void
+gs_lock_plug_enable_prompt (GSLockPlug *plug,
+                            const char *message,
+                            gboolean    visible)
+{
+	g_return_if_fail (GS_IS_LOCK_PLUG (plug));
+
+	gs_debug ("Setting prompt to: %s", message);
+
+	gtk_widget_set_sensitive (plug->priv->auth_unlock_button, TRUE);
+	gtk_widget_show (plug->priv->auth_unlock_button);
+	gtk_widget_grab_default (plug->priv->auth_unlock_button);
+	gtk_label_set_text (GTK_LABEL (plug->priv->auth_prompt_label), message);
+	gtk_widget_show (plug->priv->auth_prompt_label);
+	gtk_entry_set_visibility (GTK_ENTRY (plug->priv->auth_prompt_entry), visible);
+	gtk_widget_set_sensitive (plug->priv->auth_prompt_entry, TRUE);
+	gtk_widget_show (plug->priv->auth_prompt_entry);
+
+	if (! gtk_widget_has_focus (plug->priv->auth_prompt_entry))
+	{
+		gtk_widget_grab_focus (plug->priv->auth_prompt_entry);
+	}
+
+	/* were there any key events sent to the plug while the
+	 * entry wasnt ready? If so, forward them along
+	 */
+	forward_key_events (plug);
+
+	restart_cancel_timeout (plug);
+}
+
+void
+gs_lock_plug_disable_prompt (GSLockPlug *plug)
+{
+	g_return_if_fail (GS_IS_LOCK_PLUG (plug));
+
+	/* gtk_widget_hide (plug->priv->auth_prompt_entry); */
+	/* gtk_widget_hide (plug->priv->auth_prompt_label); */
+	gtk_widget_set_sensitive (plug->priv->auth_unlock_button, FALSE);
+	gtk_widget_set_sensitive (plug->priv->auth_prompt_entry, FALSE);
+	/* gtk_widget_hide (plug->priv->auth_unlock_button); */
+
+	gtk_widget_grab_default (plug->priv->auth_cancel_button);
+}
+
+void
+gs_lock_plug_show_message (GSLockPlug *plug,
+                           const char *message)
+{
+	g_return_if_fail (GS_IS_LOCK_PLUG (plug));
+
+	set_status_text (plug, message ? message : "");
+}
+
+/* button press handler used to inhibit popup menu */
+static gint
+entry_button_press (GtkWidget      *widget,
+                    GdkEventButton *event)
+{
+	if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
+	{
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gint
+entry_key_press (GtkWidget   *widget,
+                 GdkEventKey *event,
+                 GSLockPlug  *plug)
+{
+	restart_cancel_timeout (plug);
+
+	/* if the input widget is visible and ready for input
+	 * then just carry on as usual
+	 */
+	if (gtk_widget_get_visible (plug->priv->auth_prompt_entry) &&
+	        gtk_widget_is_sensitive (plug->priv->auth_prompt_entry))
+	{
+		return FALSE;
+	}
+
+	if (strcmp (event->string, "") == 0)
+	{
+		return FALSE;
+	}
+
+	queue_key_event (plug, event);
+
+	return TRUE;
+}
+
+/* adapted from gtk_dialog_add_button */
+static GtkWidget *
+gs_lock_plug_add_button (GSLockPlug  *plug,
+                         GtkWidget   *action_area,
+                         const gchar *button_text)
+{
+	GtkWidget *button;
+
+	g_return_val_if_fail (GS_IS_LOCK_PLUG (plug), NULL);
+	g_return_val_if_fail (button_text != NULL, NULL);
+
+	button = GTK_WIDGET (g_object_new (GTK_TYPE_BUTTON,
+	                                   "label", button_text,
+	                                   "use-stock", TRUE,
+	                                   "use-underline", TRUE,
+	                                   NULL));
+
+	gtk_widget_set_can_default (button, TRUE);
+
+	gtk_widget_show (button);
+
+	gtk_box_pack_end (GTK_BOX (action_area),
+	                  button,
+	                  FALSE, TRUE, 0);
+
+	return button;
+}
+
+static char *
+get_user_display_name (void)
+{
+	const char *name;
+	char       *utf8_name;
+
+	name = g_get_real_name ();
+
+	if (name == NULL || g_strcmp0 (name, "") == 0 ||
+	    g_strcmp0 (name, "Unknown") == 0)
+	{
+		name = g_get_user_name ();
+	}
+
+	utf8_name = NULL;
+
+	if (name != NULL)
+	{
+		utf8_name = g_locale_to_utf8 (name, -1, NULL, NULL, NULL);
+	}
+
+	return utf8_name;
+}
+
+static char *
+get_user_name (void)
+{
+	const char *name;
+	char       *utf8_name;
+
+	name = g_get_user_name ();
+
+	utf8_name = NULL;
+	if (name != NULL)
+	{
+		utf8_name = g_locale_to_utf8 (name, -1, NULL, NULL, NULL);
+	}
+
+	return utf8_name;
+}
+
+static void
+create_page_one_buttons (GSLockPlug *plug)
+{
+
+	gs_profile_start ("page one buttons");
+
+	plug->priv->auth_switch_button =  gs_lock_plug_add_button (GS_LOCK_PLUG (plug),
+	                                  plug->priv->auth_action_area,
+	                                  _("S_witch User..."));
+	gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (plug->priv->auth_action_area),
+	                                    plug->priv->auth_switch_button,
+	                                    TRUE);
+	gtk_widget_set_focus_on_click (GTK_WIDGET (plug->priv->auth_switch_button), FALSE);
+	gtk_widget_set_no_show_all (plug->priv->auth_switch_button, TRUE);
+
+	plug->priv->auth_logout_button =  gs_lock_plug_add_button (GS_LOCK_PLUG (plug),
+	                                  plug->priv->auth_action_area,
+	                                  _("Log _Out"));
+	gtk_widget_set_focus_on_click (GTK_WIDGET (plug->priv->auth_logout_button), FALSE);
+	gtk_widget_set_no_show_all (plug->priv->auth_logout_button, TRUE);
+
+	plug->priv->auth_cancel_button =  gs_lock_plug_add_button (GS_LOCK_PLUG (plug),
+	                                  plug->priv->auth_action_area,
+	                                  "gtk-cancel");
+	gtk_widget_set_focus_on_click (GTK_WIDGET (plug->priv->auth_cancel_button), FALSE);
+
+	plug->priv->auth_unlock_button =  gs_lock_plug_add_button (GS_LOCK_PLUG (plug),
+	                                  plug->priv->auth_action_area,
+	                                  _("_Unlock"));
+	gtk_widget_set_focus_on_click (GTK_WIDGET (plug->priv->auth_unlock_button), FALSE);
+
+	gtk_window_set_default (GTK_WINDOW (plug), plug->priv->auth_unlock_button);
+
+	gs_profile_end ("page one buttons");
+}
+
+/* adapted from MDM */
+static char *
+expand_string (const char *text)
+{
+	GString       *str;
+	const char    *p;
+	char          *username;
+	glong          i;
+	glong          n_chars;
+	struct utsname name;
+
+	str = g_string_sized_new (strlen (text));
+
+	p = text;
+	n_chars = g_utf8_strlen (text, -1);
+	i = 0;
+
+	while (i < n_chars)
+	{
+		gunichar ch;
+
+		ch = g_utf8_get_char (p);
+
+		/* Backslash commands */
+		if (ch == '\\')
+		{
+			p = g_utf8_next_char (p);
+			i++;
+			ch = g_utf8_get_char (p);
+
+			if (i >= n_chars || ch == '\0')
+			{
+				g_warning ("Unescaped \\ at end of text\n");
+				goto bail;
+			}
+			else if (ch == 'n')
+			{
+				g_string_append_unichar (str, '\n');
+			}
+			else
+			{
+				g_string_append_unichar (str, ch);
+			}
+		}
+		else if (ch == '%')
+		{
+			p = g_utf8_next_char (p);
+			i++;
+			ch = g_utf8_get_char (p);
+
+			if (i >= n_chars || ch == '\0')
+			{
+				g_warning ("Unescaped %% at end of text\n");
+				goto bail;
+			}
+
+			switch (ch)
+			{
+			case '%':
+				g_string_append (str, "%");
+				break;
+			case 'c':
+				/* clock */
+				break;
+			case 'd':
+				/* display */
+				g_string_append (str, g_getenv ("DISPLAY"));
+				break;
+			case 'h':
+				/* hostname */
+				g_string_append (str, g_get_host_name ());
+				break;
+			case 'm':
+				/* machine name */
+				uname (&name);
+				g_string_append (str, name.machine);
+				break;
+			case 'n':
+				/* nodename */
+				uname (&name);
+				g_string_append (str, name.nodename);
+				break;
+			case 'r':
+				/* release */
+				uname (&name);
+				g_string_append (str, name.release);
+				break;
+			case 'R':
+				/* Real name */
+				username = get_user_display_name ();
+				g_string_append (str, username);
+				g_free (username);
+				break;
+			case 's':
+				/* system name */
+				uname (&name);
+				g_string_append (str, name.sysname);
+				break;
+			case 'U':
+				/* Username */
+				username = get_user_name ();
+				g_string_append (str, username);
+				g_free (username);
+				break;
+			default:
+				if (ch < 127)
+				{
+					g_warning ("unknown escape code %%%c in text\n", (char)ch);
+				}
+				else
+				{
+					g_warning ("unknown escape code %%(U%x) in text\n", (int)ch);
+				}
+			}
+		}
+		else
+		{
+			g_string_append_unichar (str, ch);
+		}
+		p = g_utf8_next_char (p);
+		i++;
+	}
+
+bail:
+
+	return g_string_free (str, FALSE);
+}
+
+static void
+expand_string_for_label (GtkWidget *label)
+{
+	const char *template;
+	char       *str;
+
+	template = gtk_label_get_label (GTK_LABEL (label));
+	str = expand_string (template);
+	gtk_label_set_label (GTK_LABEL (label), str);
+	g_free (str);
+}
+
+static void
+create_page_one (GSLockPlug *plug)
+{
+	GtkWidget            *vbox;
+	GtkWidget            *vbox2;
+	GtkWidget            *hbox;
+	char                 *str;
+
+	gs_profile_start ("page one");
+
+	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+	gtk_widget_set_halign (GTK_WIDGET (vbox),
+	                       GTK_ALIGN_CENTER);
+	gtk_widget_set_valign (GTK_WIDGET (vbox),
+	                       GTK_ALIGN_CENTER);
+	gtk_notebook_append_page (GTK_NOTEBOOK (plug->priv->notebook), vbox, NULL);
+
+	vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
+
+	str = g_strdup ("<span size=\"xx-large\" weight=\"ultrabold\">%s</span>");
+	plug->priv->auth_time_label = gtk_label_new (str);
+	g_free (str);
+	gtk_label_set_xalign (GTK_LABEL (plug->priv->auth_time_label), 0.5);
+	gtk_label_set_yalign (GTK_LABEL (plug->priv->auth_time_label), 0.5);
+	gtk_label_set_use_markup (GTK_LABEL (plug->priv->auth_time_label), TRUE);
+	gtk_box_pack_start (GTK_BOX (vbox2), plug->priv->auth_time_label, FALSE, FALSE, 0);
+
+	str = g_strdup ("<span size=\"large\">%s</span>");
+	plug->priv->auth_date_label = gtk_label_new (str);
+	g_free (str);
+	gtk_label_set_xalign (GTK_LABEL (plug->priv->auth_date_label), 0.5);
+	gtk_label_set_yalign (GTK_LABEL (plug->priv->auth_date_label), 0.5);
+	gtk_label_set_use_markup (GTK_LABEL (plug->priv->auth_date_label), TRUE);
+	gtk_box_pack_start (GTK_BOX (vbox2), plug->priv->auth_date_label, FALSE, FALSE, 0);
+
+	plug->priv->auth_face_image = gtk_image_new ();
+	gtk_box_pack_start (GTK_BOX (vbox), plug->priv->auth_face_image, TRUE, TRUE, 0);
+	gtk_widget_set_halign (plug->priv->auth_face_image, GTK_ALIGN_CENTER);
+	gtk_widget_set_valign (plug->priv->auth_face_image, GTK_ALIGN_END);
+
+	vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
+
+	str = g_strdup ("<span size=\"x-large\">%R</span>");
+	plug->priv->auth_realname_label = gtk_label_new (str);
+	g_free (str);
+	expand_string_for_label (plug->priv->auth_realname_label);
+	gtk_label_set_xalign (GTK_LABEL (plug->priv->auth_realname_label), 0.5);
+	gtk_label_set_yalign (GTK_LABEL (plug->priv->auth_realname_label), 0.5);
+	gtk_label_set_use_markup (GTK_LABEL (plug->priv->auth_realname_label), TRUE);
+	gtk_box_pack_start (GTK_BOX (vbox2), plug->priv->auth_realname_label, FALSE, FALSE, 0);
+
+	/* To translators: This expands to USERNAME on HOSTNAME */
+	str = g_strdup_printf ("<span size=\"small\">%s</span>", _("%U on %h"));
+	plug->priv->auth_username_label = gtk_label_new (str);
+	g_free (str);
+	expand_string_for_label (plug->priv->auth_username_label);
+	gtk_label_set_xalign (GTK_LABEL (plug->priv->auth_realname_label), 0.5);
+	gtk_label_set_yalign (GTK_LABEL (plug->priv->auth_realname_label), 0.5);
+	gtk_label_set_use_markup (GTK_LABEL (plug->priv->auth_username_label), TRUE);
+	gtk_box_pack_start (GTK_BOX (vbox2), plug->priv->auth_username_label, FALSE, FALSE, 0);
+
+	vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0);
+
+	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+	gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
+
+	plug->priv->auth_prompt_label = gtk_label_new_with_mnemonic (_("_Password:"));
+	gtk_label_set_xalign (GTK_LABEL (plug->priv->auth_prompt_label), 0.0);
+	gtk_label_set_yalign (GTK_LABEL (plug->priv->auth_prompt_label), 0.5);
+	gtk_box_pack_start (GTK_BOX (hbox), plug->priv->auth_prompt_label, FALSE, FALSE, 0);
+
+	plug->priv->auth_prompt_entry = gtk_entry_new ();
+	gtk_box_pack_start (GTK_BOX (hbox), plug->priv->auth_prompt_entry, TRUE, TRUE, 0);
+
+	gtk_label_set_mnemonic_widget (GTK_LABEL (plug->priv->auth_prompt_label),
+	                               plug->priv->auth_prompt_entry);
+
+	plug->priv->auth_capslock_label = gtk_label_new ("");
+	gtk_label_set_xalign (GTK_LABEL (plug->priv->auth_capslock_label), 0.5);
+	gtk_label_set_yalign (GTK_LABEL (plug->priv->auth_capslock_label), 0.5);
+	gtk_box_pack_start (GTK_BOX (vbox2), plug->priv->auth_capslock_label, FALSE, FALSE, 0);
+
+	/* Status text */
+
+	plug->priv->auth_message_label = gtk_label_new (NULL);
+	gtk_box_pack_start (GTK_BOX (vbox), plug->priv->auth_message_label,
+	                    FALSE, FALSE, 0);
+	/* Buttons */
+	plug->priv->auth_action_area = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
+
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (plug->priv->auth_action_area),
+	                           GTK_BUTTONBOX_END);
+
+	gtk_box_pack_end (GTK_BOX (vbox), plug->priv->auth_action_area,
+	                  FALSE, TRUE, 0);
+	gtk_widget_show (plug->priv->auth_action_area);
+
+	create_page_one_buttons (plug);
+
+	gs_profile_end ("page one");
+}
+
+static void
+unlock_button_clicked (GtkButton  *button,
+                       GSLockPlug *plug)
+{
+	gs_lock_plug_response (plug, GS_LOCK_PLUG_RESPONSE_OK);
+}
+
+static void
+cancel_button_clicked (GtkButton  *button,
+                       GSLockPlug *plug)
+{
+	gs_lock_plug_response (plug, GS_LOCK_PLUG_RESPONSE_CANCEL);
+}
+
+static void
+switch_user_button_clicked (GtkButton  *button,
+                            GSLockPlug *plug)
+{
+
+	remove_response_idle (plug);
+
+	gs_lock_plug_set_sensitive (plug, FALSE);
+
+	plug->priv->response_idle_id = g_timeout_add (2000,
+	                                              response_cancel_idle_cb,
+	                                              plug);
+
+	gs_lock_plug_set_busy (plug);
+	do_user_switch (plug);
+}
+
+static char *
+get_dialog_theme_name (GSLockPlug *plug)
+{
+	char        *name;
+	GSettings *settings;
+
+	settings = g_settings_new (GSETTINGS_SCHEMA);
+	name = g_settings_get_string (settings, KEY_LOCK_DIALOG_THEME);
+	g_object_unref (settings);
+
+	return name;
+}
+
+static gboolean
+load_theme (GSLockPlug *plug)
+{
+	char       *theme;
+	char       *filename;
+	char       *gtkbuilder;
+	char       *css;
+	GtkBuilder *builder;
+	GtkWidget  *lock_dialog;
+	GError     *error=NULL;
+
+	theme = get_dialog_theme_name (plug);
+	if (theme == NULL)
+	{
+		return FALSE;
+	}
+
+	filename = g_strdup_printf ("lock-dialog-%s.ui", theme);
+	gtkbuilder = g_build_filename (GTKBUILDERDIR, filename, NULL);
+	g_free (filename);
+	if (! g_file_test (gtkbuilder, G_FILE_TEST_IS_REGULAR))
+	{
+		g_free (gtkbuilder);
+		g_free (theme);
+		return FALSE;
+	}
+
+	filename = g_strdup_printf ("lock-dialog-%s.css", theme);
+	g_free (theme);
+	css = g_build_filename (GTKBUILDERDIR, filename, NULL);
+	g_free (filename);
+	if (g_file_test (css, G_FILE_TEST_IS_REGULAR))
+	{
+		static GtkCssProvider *style_provider = NULL;
+
+		if (style_provider == NULL)
+		{
+			style_provider = gtk_css_provider_new ();
+
+			gtk_style_context_add_provider_for_screen (gdk_screen_get_default(),
+			                                           GTK_STYLE_PROVIDER (style_provider),
+			                                           GTK_STYLE_PROVIDER_PRIORITY_USER);
+		}
+
+		gtk_css_provider_load_from_path (style_provider, css, NULL);
+	}
+	g_free (css);
+
+	builder = gtk_builder_new();
+	if (!gtk_builder_add_from_file (builder,gtkbuilder,&error))
+	{
+		g_warning ("Couldn't load builder file '%s': %s", gtkbuilder, error->message);
+		g_error_free(error);
+		g_free (gtkbuilder);
+		return FALSE;
+	}
+	g_free (gtkbuilder);
+
+	lock_dialog = GTK_WIDGET (gtk_builder_get_object(builder, "lock-dialog"));
+	gtk_container_add (GTK_CONTAINER (plug), lock_dialog);
+
+	plug->priv->vbox = NULL;
+	plug->priv->notebook = GTK_WIDGET (gtk_builder_get_object(builder, "notebook"));
+
+	plug->priv->auth_face_image = GTK_WIDGET (gtk_builder_get_object(builder, "auth-face-image"));
+	plug->priv->auth_action_area = GTK_WIDGET (gtk_builder_get_object(builder, "auth-action-area"));
+	plug->priv->auth_time_label = GTK_WIDGET (gtk_builder_get_object(builder, "auth-time-label"));
+	plug->priv->auth_date_label = GTK_WIDGET (gtk_builder_get_object(builder, "auth-date-label"));
+	plug->priv->auth_realname_label = GTK_WIDGET (gtk_builder_get_object(builder, "auth-realname-label"));
+	plug->priv->auth_username_label = GTK_WIDGET (gtk_builder_get_object(builder, "auth-username-label"));
+	plug->priv->auth_prompt_label = GTK_WIDGET (gtk_builder_get_object(builder, "auth-prompt-label"));
+	plug->priv->auth_prompt_entry = GTK_WIDGET (gtk_builder_get_object(builder, "auth-prompt-entry"));
+	plug->priv->auth_prompt_box = GTK_WIDGET (gtk_builder_get_object(builder, "auth-prompt-box"));
+	plug->priv->auth_capslock_label = GTK_WIDGET (gtk_builder_get_object(builder, "auth-capslock-label"));
+	plug->priv->auth_message_label = GTK_WIDGET (gtk_builder_get_object(builder, "auth-status-label"));
+	plug->priv->auth_unlock_button = GTK_WIDGET (gtk_builder_get_object(builder, "auth-unlock-button"));
+	plug->priv->auth_cancel_button = GTK_WIDGET (gtk_builder_get_object(builder, "auth-cancel-button"));
+	plug->priv->auth_logout_button = GTK_WIDGET (gtk_builder_get_object(builder, "auth-logout-button"));
+	plug->priv->auth_switch_button = GTK_WIDGET (gtk_builder_get_object(builder, "auth-switch-button"));
+	plug->priv->auth_note_button = GTK_WIDGET (gtk_builder_get_object(builder, "auth-note-button"));
+	plug->priv->note_tab = GTK_WIDGET (gtk_builder_get_object(builder, "note-tab"));
+	plug->priv->note_tab_label = GTK_WIDGET (gtk_builder_get_object(builder, "note-tab-label"));
+	plug->priv->note_ok_button = GTK_WIDGET (gtk_builder_get_object(builder, "note-ok-button"));
+	plug->priv->note_text_view = GTK_WIDGET (gtk_builder_get_object(builder, "note-text-view"));
+	plug->priv->note_cancel_button = GTK_WIDGET (gtk_builder_get_object(builder, "note-cancel-button"));
+
+	/* Placeholder for the keyboard indicator */
+	plug->priv->auth_prompt_kbd_layout_indicator = GTK_WIDGET (gtk_builder_get_object(builder, "auth-prompt-kbd-layout-indicator"));
+	if (plug->priv->auth_logout_button != NULL)
+	{
+		gtk_widget_set_no_show_all (plug->priv->auth_logout_button, TRUE);
+	}
+	if (plug->priv->auth_switch_button != NULL)
+	{
+		gtk_widget_set_no_show_all (plug->priv->auth_switch_button, TRUE);
+	}
+	if (plug->priv->auth_note_button != NULL)
+	{
+		gtk_widget_set_no_show_all (plug->priv->auth_note_button, TRUE);
+	}
+
+	date_time_update (plug);
+	gtk_widget_show_all (lock_dialog);
+
+	plug->priv->status_message_label = GTK_WIDGET (gtk_builder_get_object(builder, "status-message-label"));
+
+	return TRUE;
+}
+
+static int
+delete_handler (GSLockPlug  *plug,<--- Shadowed declaration
+                GdkEventAny *event,
+                gpointer     data)
+{
+	gs_lock_plug_response (plug, GS_LOCK_PLUG_RESPONSE_CANCEL);
+
+	return TRUE; /* Do not destroy */
+}
+
+static void
+on_note_text_buffer_changed (GtkTextBuffer *buffer,
+                             GSLockPlug    *plug)
+{
+	int len;
+
+	len = gtk_text_buffer_get_char_count (buffer);
+	gtk_widget_set_sensitive (plug->priv->note_ok_button, len <= NOTE_BUFFER_MAX_CHARS);
+}
+
+static void
+entry_icon_clicked (GtkEntry       *entry,
+                    gint            position,
+                    GdkEventButton *event,
+                    gpointer        data)
+{
+	(void)data;
+
+	if ((position == GTK_ENTRY_ICON_SECONDARY) && (event->type == GDK_DOUBLE_BUTTON_PRESS))
+	{
+		if (g_strcmp0 (gtk_entry_get_icon_name (entry, position), "emblem-readonly"))
+		{
+			gtk_entry_set_icon_from_icon_name (entry, position, "emblem-readonly");
+			gtk_entry_set_icon_tooltip_text (entry, position, _("Show password"));
+			gtk_entry_set_visibility (entry, FALSE);
+		}
+		else
+		{
+			gtk_entry_set_icon_from_icon_name (entry, position, "emblem-unreadable");
+			gtk_entry_set_icon_tooltip_text (entry, position, _("Hide password"));
+			gtk_entry_set_visibility (entry, TRUE);
+		}
+	}
+}
+static void
+gs_lock_plug_init (GSLockPlug *plug)
+{
+	gs_profile_start (NULL);
+
+	plug->priv = gs_lock_plug_get_instance_private (plug);
+
+	clear_clipboards (plug);
+
+#ifdef WITH_LIBNOTIFY
+	notify_init ("mate-screensaver-dialog");
+	plug->priv->leave_note_enabled = TRUE;
+#else
+	plug->priv->leave_note_enabled = FALSE;
+#endif
+
+	GtkStyleContext *context;
+
+	context = gtk_widget_get_style_context (GTK_WIDGET (plug));
+	gtk_style_context_add_class (context, "lock-dialog");
+
+	if (! load_theme (plug))
+	{
+		gs_debug ("Unable to load theme!");
+
+		plug->priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+		gtk_container_add (GTK_CONTAINER (plug), plug->priv->vbox);
+
+		/* Notebook */
+
+		plug->priv->notebook = gtk_notebook_new ();
+		gtk_notebook_set_show_tabs (GTK_NOTEBOOK (plug->priv->notebook), FALSE);
+		gtk_notebook_set_show_border (GTK_NOTEBOOK (plug->priv->notebook), FALSE);
+		gtk_box_pack_start (GTK_BOX (plug->priv->vbox), plug->priv->notebook, TRUE, TRUE, 0);
+
+		/* Page 1 */
+
+		create_page_one (plug);
+
+		date_time_update (plug);
+		gtk_widget_show_all (plug->priv->vbox);
+	}
+	plug->priv->datetime_timeout_id = g_timeout_add_seconds (1, G_SOURCE_FUNC (date_time_update), plug);
+
+	if (plug->priv->note_text_view != NULL)
+	{
+		GtkTextBuffer *buffer;
+		buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (plug->priv->note_text_view));
+		g_signal_connect (buffer, "changed", G_CALLBACK (on_note_text_buffer_changed), plug);
+	}
+
+	/* Layout indicator */
+#ifdef WITH_KBD_LAYOUT_INDICATOR
+	if (plug->priv->auth_prompt_kbd_layout_indicator != NULL)
+	{
+		XklEngine *engine;
+
+		engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+		if (xkl_engine_get_num_groups (engine) > 1)
+		{
+			GtkWidget *layout_indicator;
+
+			layout_indicator = matekbd_indicator_new ();
+			matekbd_indicator_set_parent_tooltips (MATEKBD_INDICATOR (layout_indicator), TRUE);
+			gtk_box_pack_start (GTK_BOX (plug->priv->auth_prompt_kbd_layout_indicator),
+			                    layout_indicator,
+			                    FALSE,
+			                    FALSE,
+			                    6);
+
+			gtk_widget_show_all (layout_indicator);
+			gtk_widget_show (plug->priv->auth_prompt_kbd_layout_indicator);
+		}
+		else
+		{
+			gtk_widget_hide (plug->priv->auth_prompt_kbd_layout_indicator);
+		}
+
+		g_object_unref (engine);
+	}
+#endif
+
+	if (plug->priv->auth_note_button != NULL)
+	{
+		if (plug->priv->leave_note_enabled)
+		{
+			gtk_widget_show_all (plug->priv->auth_note_button);
+		}
+		else
+		{
+			gtk_widget_hide (plug->priv->auth_note_button);
+		}
+	}
+	if (plug->priv->auth_switch_button != NULL)
+	{
+		if (plug->priv->switch_enabled)
+		{
+			gtk_widget_show_all (plug->priv->auth_switch_button);
+		}
+		else
+		{
+			gtk_widget_hide (plug->priv->auth_switch_button);
+		}
+	}
+
+	gtk_widget_grab_default (plug->priv->auth_unlock_button);
+
+	if (plug->priv->auth_username_label != NULL)
+	{
+		expand_string_for_label (plug->priv->auth_username_label);
+	}
+
+	if (plug->priv->auth_realname_label != NULL)
+	{
+		expand_string_for_label (plug->priv->auth_realname_label);
+	}
+
+	if (! plug->priv->logout_enabled || ! plug->priv->logout_command)
+	{
+		if (plug->priv->auth_logout_button != NULL)
+		{
+			gtk_widget_hide (plug->priv->auth_logout_button);
+		}
+	}
+
+	plug->priv->timeout = DIALOG_TIMEOUT_MSEC;
+
+	g_signal_connect (plug, "key_press_event",
+	                  G_CALLBACK (entry_key_press), plug);
+
+	/* button press handler used to inhibit popup menu */
+	g_signal_connect (plug->priv->auth_prompt_entry, "button_press_event",
+	                  G_CALLBACK (entry_button_press), NULL);
+	gtk_entry_set_activates_default (GTK_ENTRY (plug->priv->auth_prompt_entry), TRUE);
+	gtk_entry_set_visibility (GTK_ENTRY (plug->priv->auth_prompt_entry), FALSE);
+
+	/* show/hide password */
+	g_signal_connect (plug->priv->auth_prompt_entry, "icon-press",
+	                  G_CALLBACK (entry_icon_clicked), NULL);
+
+	g_signal_connect (plug->priv->auth_unlock_button, "clicked",
+	                  G_CALLBACK (unlock_button_clicked), plug);
+
+	g_signal_connect (plug->priv->auth_cancel_button, "clicked",
+	                  G_CALLBACK (cancel_button_clicked), plug);
+
+	if (plug->priv->status_message_label)
+	{
+		if (plug->priv->status_message)
+		{
+			gtk_label_set_text (GTK_LABEL (plug->priv->status_message_label),
+			                    plug->priv->status_message);
+		}
+		else
+		{
+			gtk_widget_hide (plug->priv->status_message_label);
+		}
+	}
+
+	if (plug->priv->auth_switch_button != NULL)
+	{
+		g_signal_connect (plug->priv->auth_switch_button, "clicked",
+		                  G_CALLBACK (switch_user_button_clicked), plug);
+	}
+
+	if (plug->priv->auth_note_button != NULL)
+	{
+		g_signal_connect (plug->priv->auth_note_button, "clicked",
+		                  G_CALLBACK (take_note), plug);
+		g_signal_connect (plug->priv->note_ok_button, "clicked",
+		                  G_CALLBACK (submit_note), plug);
+		g_signal_connect (plug->priv->note_cancel_button, "clicked",
+		                  G_CALLBACK (cancel_note), plug);
+	}
+
+	if (plug->priv->note_tab_label != NULL)
+	{
+		expand_string_for_label (plug->priv->note_tab_label);
+	}
+
+	if (plug->priv->auth_logout_button != NULL)
+	{
+		g_signal_connect (plug->priv->auth_logout_button, "clicked",
+		                  G_CALLBACK (logout_button_clicked), plug);
+	}
+
+	g_signal_connect (plug, "delete_event", G_CALLBACK (delete_handler), NULL);
+
+	gs_profile_end (NULL);
+}
+
+static void
+gs_lock_plug_finalize (GObject *object)
+{
+	GSLockPlug *plug;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GS_IS_LOCK_PLUG (object));
+
+	plug = GS_LOCK_PLUG (object);
+
+	g_return_if_fail (plug->priv != NULL);
+
+	g_free (plug->priv->logout_command);
+
+	remove_response_idle (plug);
+	remove_cancel_timeout (plug);
+	remove_datetime_timeout (plug);
+#ifdef WITH_LIBNOTIFY
+	notify_uninit ();
+#endif
+
+	G_OBJECT_CLASS (gs_lock_plug_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gs_lock_plug_new (void)
+{
+	GtkWidget *result;
+
+	result = g_object_new (GS_TYPE_LOCK_PLUG, NULL);
+
+	gtk_window_set_focus_on_map (GTK_WINDOW (result), TRUE);
+
+	return result;
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/13.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/13.html new file mode 100644 index 0000000..58a8267 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/13.html @@ -0,0 +1,4171 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2008 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <time.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#define MATE_DESKTOP_USE_UNSTABLE_API
+#include <libmate-desktop/mate-bg.h>
+
+#include "gs-prefs.h"        /* for GSSaverMode */
+
+#include "gs-manager.h"
+#include "gs-window.h"
+#include "gs-theme-manager.h"
+#include "gs-job.h"
+#include "gs-grab.h"
+#include "gs-fade.h"
+#include "gs-debug.h"
+
+static void gs_manager_finalize   (GObject        *object);
+
+struct GSManagerPrivate
+{
+	GSList      *windows;
+	GHashTable  *jobs;
+
+	GSThemeManager *theme_manager;
+	MateBG        *bg;
+
+	/* Policy */
+	glong        lock_timeout;
+	glong        cycle_timeout;
+	glong        logout_timeout;
+
+	guint        lock_enabled : 1;
+	guint        logout_enabled : 1;
+	guint        keyboard_enabled : 1;
+	guint        user_switch_enabled : 1;
+	guint        throttled : 1;
+
+	char        *logout_command;
+	char        *keyboard_command;
+
+	char        *status_message;
+
+	/* State */
+	guint        active : 1;
+	guint        lock_active : 1;
+
+	guint        fading : 1;
+	guint        dialog_up : 1;
+
+	time_t       activate_time;
+
+	guint        lock_timeout_id;
+	guint        cycle_timeout_id;
+
+	GSList      *themes;
+	GSSaverMode  saver_mode;
+	GSGrab      *grab;
+	GSFade      *fade;
+	guint        unfade_idle_id;
+};
+
+enum
+{
+    ACTIVATED,
+    DEACTIVATED,
+    AUTH_REQUEST_BEGIN,
+    AUTH_REQUEST_END,
+    LAST_SIGNAL
+};
+
+enum
+{
+    PROP_0,
+    PROP_LOCK_ENABLED,
+    PROP_LOGOUT_ENABLED,
+    PROP_USER_SWITCH_ENABLED,
+    PROP_KEYBOARD_ENABLED,
+    PROP_LOCK_TIMEOUT,
+    PROP_CYCLE_TIMEOUT,
+    PROP_LOGOUT_TIMEOUT,
+    PROP_LOGOUT_COMMAND,
+    PROP_KEYBOARD_COMMAND,
+    PROP_STATUS_MESSAGE,
+    PROP_ACTIVE,
+    PROP_THROTTLED,
+};
+
+#define FADE_TIMEOUT 250
+
+static guint         signals [LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSManager, gs_manager, G_TYPE_OBJECT)
+
+static void
+manager_add_job_for_window (GSManager *manager,
+                            GSWindow  *window,
+                            GSJob     *job)
+{
+	if (manager->priv->jobs == NULL)
+	{
+		return;
+	}
+
+	g_hash_table_insert (manager->priv->jobs, window, job);
+}
+
+static const char *
+select_theme (GSManager *manager)
+{
+	const char *theme = NULL;
+
+	g_return_val_if_fail (manager != NULL, NULL);
+	g_return_val_if_fail (GS_IS_MANAGER (manager), NULL);
+
+	if (manager->priv->saver_mode == GS_MODE_BLANK_ONLY)
+	{
+		return NULL;
+	}
+
+	if (manager->priv->themes)
+	{
+		int number = 0;
+
+		if (manager->priv->saver_mode == GS_MODE_RANDOM)
+		{
+			g_random_set_seed (time (NULL));
+			number = g_random_int_range (0, g_slist_length (manager->priv->themes));
+		}
+		theme = g_slist_nth_data (manager->priv->themes, number);
+	}
+
+	return theme;
+}
+
+static GSJob *
+lookup_job_for_window (GSManager *manager,
+                       GSWindow  *window)
+{
+	GSJob *job;
+
+	if (manager->priv->jobs == NULL)
+	{
+		return NULL;
+	}
+
+	job = g_hash_table_lookup (manager->priv->jobs, window);
+
+	return job;
+}
+
+static void
+manager_maybe_stop_job_for_window (GSManager *manager,
+                                   GSWindow  *window)
+{
+	GSJob *job;
+
+	job = lookup_job_for_window (manager, window);
+
+	if (job == NULL)
+	{
+		gs_debug ("Job not found for window");
+		return;
+	}
+
+	gs_job_stop (job);
+}
+
+static void
+manager_maybe_start_job_for_window (GSManager *manager,
+                                    GSWindow  *window)
+{
+	GSJob *job;
+
+	job = lookup_job_for_window (manager, window);
+
+	if (job == NULL)
+	{
+		gs_debug ("Job not found for window");
+		return;
+	}
+
+	if (! manager->priv->dialog_up)
+	{
+		if (! manager->priv->throttled)
+		{
+			if (! gs_job_is_running (job))
+			{
+				if (! gs_window_is_obscured (window))
+				{
+					gs_debug ("Starting job for window");
+					gs_job_start (job);
+				}
+				else
+				{
+					gs_debug ("Window is obscured deferring start of job");
+				}
+			}
+			else
+			{
+				gs_debug ("Not starting job because job is running");
+			}
+		}
+		else
+		{
+			gs_debug ("Not starting job because throttled");
+		}
+	}
+	else
+	{
+		gs_debug ("Not starting job because dialog is up");
+	}
+}
+
+static void
+manager_select_theme_for_job (GSManager *manager,
+                              GSJob     *job)
+{
+	const char *theme;
+
+	theme = select_theme (manager);
+
+	if (theme != NULL)
+	{
+		GSThemeInfo    *info;
+		const char     *command;
+
+		command = NULL;
+
+		info = gs_theme_manager_lookup_theme_info (manager->priv->theme_manager, theme);
+		if (info != NULL)
+		{
+			command = gs_theme_info_get_exec (info);
+		}
+		else
+		{
+			gs_debug ("Could not find information for theme: %s",
+			          theme);
+		}
+
+		gs_job_set_command (job, command);
+
+		if (info != NULL)
+		{
+			gs_theme_info_unref (info);
+		}
+	}
+	else
+	{
+		gs_job_set_command (job, NULL);
+	}
+}
+
+static void
+cycle_job (GSWindow  *window,
+           GSJob     *job,
+           GSManager *manager)
+{
+	gs_job_stop (job);
+	manager_select_theme_for_job (manager, job);
+	manager_maybe_start_job_for_window (manager, window);
+}
+
+static void
+manager_cycle_jobs (GSManager *manager)
+{
+	if (manager->priv->jobs != NULL)
+	{
+		g_hash_table_foreach (manager->priv->jobs, (GHFunc) cycle_job, manager);
+	}
+}
+
+static void
+throttle_job (GSWindow  *window,
+              GSJob     *job,
+              GSManager *manager)
+{
+	if (manager->priv->throttled)
+	{
+		gs_job_stop (job);
+	}
+	else
+	{
+		manager_maybe_start_job_for_window (manager, window);
+	}
+}
+
+static void
+manager_throttle_jobs (GSManager *manager)
+{
+	if (manager->priv->jobs != NULL)
+	{
+		g_hash_table_foreach (manager->priv->jobs, (GHFunc) throttle_job, manager);
+	}
+}
+
+static void
+resume_job (GSWindow  *window,
+            GSJob     *job,
+            GSManager *manager)
+{
+	if (gs_job_is_running (job))
+	{
+		gs_job_suspend (job, FALSE);
+	}
+	else
+	{
+		manager_maybe_start_job_for_window (manager, window);
+	}
+}
+
+static void
+manager_resume_jobs (GSManager *manager)
+{
+	if (manager->priv->jobs != NULL)
+	{
+		g_hash_table_foreach (manager->priv->jobs, (GHFunc) resume_job, manager);
+	}
+}
+
+static void
+suspend_job (GSWindow  *window,
+             GSJob     *job,
+             GSManager *manager)
+{
+	gs_job_suspend (job, TRUE);
+}
+
+static void
+manager_suspend_jobs (GSManager *manager)
+{
+	if (manager->priv->jobs != NULL)
+	{
+		g_hash_table_foreach (manager->priv->jobs, (GHFunc) suspend_job, manager);
+	}
+}
+
+static void
+manager_stop_jobs (GSManager *manager)
+{
+	if (manager->priv->jobs != NULL)
+	{
+		g_hash_table_destroy (manager->priv->jobs);
+
+	}
+	manager->priv->jobs = NULL;
+}
+
+void
+gs_manager_set_mode (GSManager  *manager,
+                     GSSaverMode mode)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	manager->priv->saver_mode = mode;
+}
+
+static void
+free_themes (GSManager *manager)
+{
+	if (manager->priv->themes)
+	{
+		g_slist_free_full (manager->priv->themes, g_free);
+	}
+}
+
+void
+gs_manager_set_themes (GSManager *manager,
+                       GSList    *themes)
+{
+	GSList *l;
+
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	free_themes (manager);
+	manager->priv->themes = NULL;
+
+	for (l = themes; l; l = l->next)
+	{
+		manager->priv->themes = g_slist_append (manager->priv->themes, g_strdup (l->data));
+	}
+}
+
+void
+gs_manager_set_throttled (GSManager *manager,
+                          gboolean   throttled)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (manager->priv->throttled != throttled)
+	{
+		GSList *l;
+
+		manager->priv->throttled = (throttled != FALSE);
+
+		if (! manager->priv->dialog_up)
+		{
+
+			manager_throttle_jobs (manager);
+
+			for (l = manager->priv->windows; l; l = l->next)
+			{
+				gs_window_clear (l->data);
+			}
+		}
+	}
+}
+
+void
+gs_manager_get_lock_active (GSManager *manager,
+                            gboolean  *lock_active)
+{
+	if (lock_active != NULL)
+	{
+		*lock_active = FALSE;
+	}
+
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (lock_active != NULL)
+	{
+		*lock_active = manager->priv->lock_active;
+	}
+}
+
+void
+gs_manager_set_lock_active (GSManager *manager,
+                            gboolean   lock_active)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	gs_debug ("Setting lock active: %d", lock_active);
+
+	if (manager->priv->lock_active != lock_active)
+	{
+		GSList *l;
+
+		manager->priv->lock_active = (lock_active != FALSE);
+		for (l = manager->priv->windows; l; l = l->next)
+		{
+			gs_window_set_lock_enabled (l->data, lock_active);
+		}
+	}
+}
+
+void
+gs_manager_get_lock_enabled (GSManager *manager,
+                             gboolean  *lock_enabled)
+{
+	if (lock_enabled != NULL)
+	{
+		*lock_enabled = FALSE;
+	}
+
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (lock_enabled != NULL)
+	{
+		*lock_enabled = manager->priv->lock_enabled;
+	}
+}
+
+void
+gs_manager_set_lock_enabled (GSManager *manager,
+                             gboolean   lock_enabled)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (manager->priv->lock_enabled != lock_enabled)
+	{
+		manager->priv->lock_enabled = (lock_enabled != FALSE);
+	}
+}
+
+void
+gs_manager_set_logout_enabled (GSManager *manager,
+                               gboolean   logout_enabled)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (manager->priv->logout_enabled != logout_enabled)
+	{
+		GSList *l;
+
+		manager->priv->logout_enabled = (logout_enabled != FALSE);
+		for (l = manager->priv->windows; l; l = l->next)
+		{
+			gs_window_set_logout_enabled (l->data, logout_enabled);
+		}
+	}
+}
+
+void
+gs_manager_set_keyboard_enabled (GSManager *manager,
+                                 gboolean   enabled)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (manager->priv->keyboard_enabled != enabled)
+	{
+		GSList *l;
+
+		manager->priv->keyboard_enabled = (enabled != FALSE);
+		for (l = manager->priv->windows; l; l = l->next)
+		{
+			gs_window_set_keyboard_enabled (l->data, enabled);
+		}
+	}
+}
+
+void
+gs_manager_set_user_switch_enabled (GSManager *manager,
+                                    gboolean   user_switch_enabled)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (manager->priv->user_switch_enabled != user_switch_enabled)
+	{
+		GSList *l;
+
+		manager->priv->user_switch_enabled = (user_switch_enabled != FALSE);
+		for (l = manager->priv->windows; l; l = l->next)
+		{
+			gs_window_set_user_switch_enabled (l->data, user_switch_enabled);
+		}
+	}
+}
+
+static gboolean
+activate_lock_timeout (GSManager *manager)
+{
+	if (manager->priv->lock_enabled)
+	{
+		gs_manager_set_lock_active (manager, TRUE);
+	}
+
+	manager->priv->lock_timeout_id = 0;
+
+	return FALSE;
+}
+
+static void
+remove_lock_timer (GSManager *manager)
+{
+	if (manager->priv->lock_timeout_id != 0)
+	{
+		g_source_remove (manager->priv->lock_timeout_id);
+		manager->priv->lock_timeout_id = 0;
+	}
+}
+
+static void
+add_lock_timer (GSManager *manager,
+                glong      timeout)
+{
+	manager->priv->lock_timeout_id = g_timeout_add (timeout,
+	                                 (GSourceFunc)activate_lock_timeout,
+	                                 manager);
+}
+
+void
+gs_manager_set_lock_timeout (GSManager *manager,
+                             glong      lock_timeout)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (manager->priv->lock_timeout != lock_timeout)
+	{
+
+		manager->priv->lock_timeout = lock_timeout;
+
+		if (manager->priv->active
+		        && ! manager->priv->lock_active
+		        && (lock_timeout >= 0))
+		{
+
+			glong elapsed = (time (NULL) - manager->priv->activate_time) * 1000;
+
+			remove_lock_timer (manager);
+
+			if (elapsed >= lock_timeout)
+			{
+				activate_lock_timeout (manager);
+			}
+			else
+			{
+				add_lock_timer (manager, lock_timeout - elapsed);
+			}
+		}
+	}
+}
+
+void
+gs_manager_set_logout_timeout (GSManager *manager,
+                               glong      logout_timeout)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (manager->priv->logout_timeout != logout_timeout)
+	{
+		GSList *l;
+
+		manager->priv->logout_timeout = logout_timeout;
+		for (l = manager->priv->windows; l; l = l->next)
+		{
+			gs_window_set_logout_timeout (l->data, logout_timeout);
+		}
+	}
+}
+
+void
+gs_manager_set_logout_command (GSManager  *manager,
+                               const char *command)
+{
+	GSList *l;
+
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	g_free (manager->priv->logout_command);
+
+	if (command)
+	{
+		manager->priv->logout_command = g_strdup (command);
+	}
+	else
+	{
+		manager->priv->logout_command = NULL;
+	}
+
+	for (l = manager->priv->windows; l; l = l->next)
+	{
+		gs_window_set_logout_command (l->data, manager->priv->logout_command);
+	}
+}
+
+void
+gs_manager_set_keyboard_command (GSManager  *manager,
+                                 const char *command)
+{
+	GSList *l;
+
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	g_free (manager->priv->keyboard_command);
+
+	if (command)
+	{
+		manager->priv->keyboard_command = g_strdup (command);
+	}
+	else
+	{
+		manager->priv->keyboard_command = NULL;
+	}
+
+	for (l = manager->priv->windows; l; l = l->next)
+	{
+		gs_window_set_keyboard_command (l->data, manager->priv->keyboard_command);
+	}
+}
+
+void
+gs_manager_set_status_message (GSManager  *manager,
+                               const char *status_message)
+{
+	GSList *l;
+
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	g_free (manager->priv->status_message);
+
+	manager->priv->status_message = g_strdup (status_message);
+
+	for (l = manager->priv->windows; l; l = l->next)
+	{
+		gs_window_set_status_message (l->data, manager->priv->status_message);
+	}
+}
+
+gboolean
+gs_manager_cycle (GSManager *manager)
+{
+	g_return_val_if_fail (manager != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE);
+
+	gs_debug ("cycling jobs");
+
+	if (! manager->priv->active)
+	{
+		return FALSE;
+	}
+
+	if (manager->priv->dialog_up)
+	{
+		return FALSE;
+	}
+
+	if (manager->priv->throttled)
+	{
+		return FALSE;
+	}
+
+	manager_cycle_jobs (manager);
+
+	return TRUE;
+}
+
+static gboolean
+cycle_timeout (GSManager *manager)
+{
+	g_return_val_if_fail (manager != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE);
+
+	if (! manager->priv->dialog_up)
+	{
+		gs_manager_cycle (manager);
+	}
+
+	return TRUE;
+}
+
+static void
+remove_cycle_timer (GSManager *manager)
+{
+	if (manager->priv->cycle_timeout_id != 0)
+	{
+		g_source_remove (manager->priv->cycle_timeout_id);
+		manager->priv->cycle_timeout_id = 0;
+	}
+}
+
+static void
+add_cycle_timer (GSManager *manager,
+                 glong      timeout)
+{
+	manager->priv->cycle_timeout_id = g_timeout_add (timeout,
+	                                  (GSourceFunc)cycle_timeout,
+	                                  manager);
+}
+
+void
+gs_manager_set_cycle_timeout (GSManager *manager,
+                              glong      cycle_timeout)
+{
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (manager->priv->cycle_timeout != cycle_timeout)
+	{
+
+		manager->priv->cycle_timeout = cycle_timeout;
+
+		if (manager->priv->active && (cycle_timeout >= 0))
+		{
+			glong timeout;
+			glong elapsed = (time (NULL) - manager->priv->activate_time) * 1000;
+
+			remove_cycle_timer (manager);
+
+			if (elapsed >= cycle_timeout)
+			{
+				timeout = 0;
+			}
+			else
+			{
+				timeout = cycle_timeout - elapsed;
+			}
+
+			add_cycle_timer (manager, timeout);
+
+		}
+	}
+}
+
+static void
+gs_manager_set_property (GObject            *object,
+                         guint               prop_id,
+                         const GValue       *value,
+                         GParamSpec         *pspec)
+{
+	GSManager *self;
+
+	self = GS_MANAGER (object);
+
+	switch (prop_id)
+	{
+	case PROP_THROTTLED:
+		gs_manager_set_throttled (self, g_value_get_boolean (value));
+		break;
+	case PROP_LOCK_ENABLED:
+		gs_manager_set_lock_enabled (self, g_value_get_boolean (value));
+		break;
+	case PROP_LOCK_TIMEOUT:
+		gs_manager_set_lock_timeout (self, g_value_get_long (value));
+		break;
+	case PROP_LOGOUT_ENABLED:
+		gs_manager_set_logout_enabled (self, g_value_get_boolean (value));
+		break;
+	case PROP_KEYBOARD_ENABLED:
+		gs_manager_set_keyboard_enabled (self, g_value_get_boolean (value));
+		break;
+	case PROP_USER_SWITCH_ENABLED:
+		gs_manager_set_user_switch_enabled (self, g_value_get_boolean (value));
+		break;
+	case PROP_LOGOUT_TIMEOUT:
+		gs_manager_set_logout_timeout (self, g_value_get_long (value));
+		break;
+	case PROP_LOGOUT_COMMAND:
+		gs_manager_set_logout_command (self, g_value_get_string (value));
+		break;
+	case PROP_KEYBOARD_COMMAND:
+		gs_manager_set_keyboard_command (self, g_value_get_string (value));
+		break;
+	case PROP_STATUS_MESSAGE:
+		gs_manager_set_status_message (self, g_value_get_string (value));
+		break;
+	case PROP_CYCLE_TIMEOUT:
+		gs_manager_set_cycle_timeout (self, g_value_get_long (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gs_manager_get_property (GObject            *object,
+                         guint               prop_id,
+                         GValue             *value,
+                         GParamSpec         *pspec)
+{
+	GSManager *self;
+
+	self = GS_MANAGER (object);
+
+	switch (prop_id)
+	{
+	case PROP_THROTTLED:
+		g_value_set_boolean (value, self->priv->throttled);
+		break;
+	case PROP_LOCK_ENABLED:
+		g_value_set_boolean (value, self->priv->lock_enabled);
+		break;
+	case PROP_LOCK_TIMEOUT:
+		g_value_set_long (value, self->priv->lock_timeout);
+		break;
+	case PROP_LOGOUT_ENABLED:
+		g_value_set_boolean (value, self->priv->logout_enabled);
+		break;
+	case PROP_KEYBOARD_ENABLED:
+		g_value_set_boolean (value, self->priv->keyboard_enabled);
+		break;
+	case PROP_USER_SWITCH_ENABLED:
+		g_value_set_boolean (value, self->priv->user_switch_enabled);
+		break;
+	case PROP_LOGOUT_TIMEOUT:
+		g_value_set_long (value, self->priv->logout_timeout);
+		break;
+	case PROP_LOGOUT_COMMAND:
+		g_value_set_string (value, self->priv->logout_command);
+		break;
+	case PROP_KEYBOARD_COMMAND:
+		g_value_set_string (value, self->priv->keyboard_command);
+		break;
+	case PROP_STATUS_MESSAGE:
+		g_value_set_string (value, self->priv->status_message);
+		break;
+	case PROP_CYCLE_TIMEOUT:
+		g_value_set_long (value, self->priv->cycle_timeout);
+		break;
+	case PROP_ACTIVE:
+		g_value_set_boolean (value, self->priv->active);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gs_manager_class_init (GSManagerClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize     = gs_manager_finalize;
+	object_class->get_property = gs_manager_get_property;
+	object_class->set_property = gs_manager_set_property;
+
+	signals [ACTIVATED] =
+	    g_signal_new ("activated",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSManagerClass, activated),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0);
+	signals [DEACTIVATED] =
+	    g_signal_new ("deactivated",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSManagerClass, deactivated),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0);
+	signals [AUTH_REQUEST_BEGIN] =
+	    g_signal_new ("auth-request-begin",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSManagerClass, auth_request_begin),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0);
+	signals [AUTH_REQUEST_END] =
+	    g_signal_new ("auth-request-end",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSManagerClass, auth_request_end),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0);
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ACTIVE,
+	                                 g_param_spec_boolean ("active",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READABLE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LOCK_ENABLED,
+	                                 g_param_spec_boolean ("lock-enabled",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LOCK_TIMEOUT,
+	                                 g_param_spec_long ("lock-timeout",
+	                                         NULL,
+	                                         NULL,
+	                                         -1,
+	                                         G_MAXLONG,
+	                                         0,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LOGOUT_ENABLED,
+	                                 g_param_spec_boolean ("logout-enabled",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_USER_SWITCH_ENABLED,
+	                                 g_param_spec_boolean ("user-switch-enabled",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_LOGOUT_TIMEOUT,
+	                                 g_param_spec_long ("logout-timeout",
+	                                         NULL,
+	                                         NULL,
+	                                         -1,
+	                                         G_MAXLONG,
+	                                         0,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LOGOUT_COMMAND,
+	                                 g_param_spec_string ("logout-command",
+	                                         NULL,
+	                                         NULL,
+	                                         NULL,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_CYCLE_TIMEOUT,
+	                                 g_param_spec_long ("cycle-timeout",
+	                                         NULL,
+	                                         NULL,
+	                                         10000,
+	                                         G_MAXLONG,
+	                                         300000,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_THROTTLED,
+	                                 g_param_spec_boolean ("throttled",
+	                                         NULL,
+	                                         NULL,
+	                                         TRUE,
+	                                         G_PARAM_READWRITE));
+}
+
+static void
+on_bg_changed (MateBG   *bg,
+               GSManager *manager)
+{
+	gs_debug ("background changed");
+}
+
+static void
+gs_manager_init (GSManager *manager)
+{
+	manager->priv = gs_manager_get_instance_private (manager);
+
+	manager->priv->fade = gs_fade_new ();
+	manager->priv->grab = gs_grab_new ();
+	manager->priv->theme_manager = gs_theme_manager_new ();
+
+	manager->priv->bg = mate_bg_new ();
+
+	g_signal_connect (manager->priv->bg,
+					  "changed",
+					  G_CALLBACK (on_bg_changed),
+					  manager);
+
+	mate_bg_load_from_preferences (manager->priv->bg);
+	GSettings *settings = g_settings_new ("org.mate.screensaver");
+	char *filename= g_settings_get_string (settings, "picture-filename");
+	if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+		mate_bg_set_filename (manager->priv->bg, filename);
+	}
+	g_free (filename);
+	g_object_unref (settings);
+}
+
+static void
+remove_timers (GSManager *manager)
+{
+	remove_lock_timer (manager);
+	remove_cycle_timer (manager);
+}
+
+static void
+remove_unfade_idle (GSManager *manager)
+{
+	if (manager->priv->unfade_idle_id > 0)
+	{
+		g_source_remove (manager->priv->unfade_idle_id);
+		manager->priv->unfade_idle_id = 0;
+	}
+}
+
+static gboolean
+window_deactivated_idle (gpointer data)
+{
+	GSManager *manager = data;
+
+	g_return_val_if_fail (manager != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE);
+
+	/* don't deactivate directly but only emit a signal
+	   so that we let the parent deactivate */
+	g_signal_emit (manager, signals [DEACTIVATED], 0);
+
+	return FALSE;
+}
+
+static void
+window_deactivated_cb (GSWindow  *window,
+                       GSManager *manager)
+{
+	g_return_if_fail (manager != NULL);
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	g_idle_add (window_deactivated_idle, manager);
+}
+
+static GSWindow *
+find_window_at_pointer (GSManager *manager)
+{
+	GdkDisplay *display;
+	GdkDevice  *device;
+	GdkMonitor *monitor;
+	int         x, y;
+	GSWindow   *window;
+	GSList     *l;
+
+	display = gdk_display_get_default ();
+
+	device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
+	gdk_device_get_position (device, NULL, &x, &y);
+	monitor = gdk_display_get_monitor_at_point (display, x, y);
+
+	/* Find the gs-window that is on that monitor */
+	window = NULL;
+	for (l = manager->priv->windows; l; l = l->next)
+	{
+		GSWindow *win = GS_WINDOW (l->data);
+		if (gs_window_get_display (win) == display &&
+		    gs_window_get_monitor (win) == monitor)
+		{
+			window = win;
+		}
+	}
+
+	if (window == NULL)
+	{
+		gs_debug ("WARNING: Could not find the GSWindow for display %s",
+		          gdk_display_get_name (display));
+		/* take the first one */
+		window = manager->priv->windows->data;
+	}
+	else
+	{
+		gs_debug ("Requesting unlock for display %s",
+		          gdk_display_get_name (display));
+	}
+
+	return window;
+}
+
+void
+gs_manager_show_message (GSManager  *manager,
+                         const char *summary,
+                         const char *body,
+                         const char *icon)
+{
+	GSWindow *window;
+
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	/* Find the GSWindow that contains the pointer */
+	window = find_window_at_pointer (manager);
+	gs_window_show_message (window, summary, body, icon);
+
+	gs_manager_request_unlock (manager);
+}
+
+static gboolean
+manager_maybe_grab_window (GSManager *manager,
+                           GSWindow  *window)
+{
+	GdkDisplay *display;
+	GdkDevice  *device;
+	GdkMonitor *monitor;
+	int         x, y;
+	gboolean    grabbed;
+
+	display = gdk_display_get_default ();
+	device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
+	gdk_device_get_position (device, NULL, &x, &y);
+	monitor = gdk_display_get_monitor_at_point (display, x, y);
+
+	gdk_display_flush (display);
+	grabbed = FALSE;
+	if (gs_window_get_display (window) == display &&
+	    gs_window_get_monitor (window) == monitor)
+	{
+		gs_debug ("Initiate grab move to %p", window);
+		gs_grab_move_to_window (manager->priv->grab,
+		                        gs_window_get_gdk_window (window),
+		                        gs_window_get_display (window),
+		                        FALSE, FALSE);
+		grabbed = TRUE;
+	}
+
+	return grabbed;
+}
+
+static void
+window_grab_broken_cb (GSWindow           *window,
+                       GdkEventGrabBroken *event,
+                       GSManager          *manager)
+{
+	GdkDisplay *display;
+	GdkSeat    *seat;
+	GdkDevice  *device;
+
+	display = gdk_window_get_display (gs_window_get_gdk_window (window));
+	seat = gdk_display_get_default_seat (display);
+
+	if (event->keyboard)
+	{
+		gs_debug ("KEYBOARD GRAB BROKEN!");
+		device = gdk_seat_get_pointer (seat);
+		if (!gdk_display_device_is_grabbed (display, device))
+			gs_grab_reset (manager->priv->grab);
+	}
+	else
+	{
+		gs_debug ("POINTER GRAB BROKEN!");
+		device = gdk_seat_get_keyboard (seat);
+		if (!gdk_display_device_is_grabbed (display, device))
+			gs_grab_reset (manager->priv->grab);
+	}
+}
+
+static gboolean
+unfade_idle (GSManager *manager)
+{
+	gs_debug ("resetting fade");
+	gs_fade_reset (manager->priv->fade);
+	manager->priv->unfade_idle_id = 0;
+	return FALSE;
+}
+
+static void
+add_unfade_idle (GSManager *manager)
+{
+	remove_unfade_idle (manager);
+	manager->priv->unfade_idle_id = g_timeout_add (500, (GSourceFunc)unfade_idle, manager);
+}
+
+static gboolean
+window_map_event_cb (GSWindow  *window,
+                     GdkEvent  *event,
+                     GSManager *manager)
+{
+	gs_debug ("Handling window map_event event");
+
+	manager_maybe_grab_window (manager, window);
+
+	manager_maybe_start_job_for_window (manager, window);
+
+	return FALSE;
+}
+
+static void
+window_map_cb (GSWindow  *window,
+               GSManager *manager)
+{
+	gs_debug ("Handling window map event");
+}
+
+static void
+window_unmap_cb (GSWindow  *window,
+                 GSManager *manager)
+{
+	gs_debug ("window unmapped!");
+}
+
+static void
+apply_background_to_window (GSManager *manager,
+                            GSWindow  *window)
+{
+	GSettings       *settings;
+	char            *filename;
+	cairo_surface_t *surface;
+	int              width;
+	int              height;
+
+	mate_bg_load_from_preferences(manager->priv->bg);
+
+	settings = g_settings_new ("org.mate.screensaver");
+	filename = g_settings_get_string (settings, "picture-filename");
+
+	if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+		mate_bg_set_filename (manager->priv->bg, filename);
+	}
+	g_free (filename);
+	g_object_unref (settings);
+
+	if (manager->priv->bg == NULL)
+	{
+		gs_debug ("No background available");
+		gs_window_set_background_surface (window, NULL);
+	}
+
+	gtk_widget_get_preferred_width (GTK_WIDGET (window), &width, NULL);
+	gtk_widget_get_preferred_height (GTK_WIDGET (window), &height, NULL);
+	gs_debug ("Creating background w:%d h:%d", width, height);
+	surface = mate_bg_create_surface (manager->priv->bg,
+	                                  gs_window_get_gdk_window (window),
+	                                  width,
+	                                  height,
+	                                  FALSE);
+	gs_window_set_background_surface (window, surface);
+	cairo_surface_destroy (surface);
+}
+
+static void
+manager_show_window (GSManager *manager,
+                     GSWindow  *window)
+{
+	GSJob *job;
+
+	apply_background_to_window (manager, window);
+
+	job = gs_job_new_for_widget (gs_window_get_drawing_area (window));
+
+	manager_select_theme_for_job (manager, job);
+	manager_add_job_for_window (manager, window, job);
+
+	manager->priv->activate_time = time (NULL);
+
+	if (manager->priv->lock_timeout >= 0)
+	{
+		remove_lock_timer (manager);
+		add_lock_timer (manager, manager->priv->lock_timeout);
+	}
+
+	if (manager->priv->cycle_timeout >= 10000)
+	{
+		remove_cycle_timer (manager);
+		add_cycle_timer (manager, manager->priv->cycle_timeout);
+	}
+
+	add_unfade_idle (manager);
+
+	/* FIXME: only emit signal once */
+	g_signal_emit (manager, signals [ACTIVATED], 0);
+}
+
+static void
+window_show_cb (GSWindow  *window,
+                GSManager *manager)
+{
+
+	g_return_if_fail (manager != NULL);
+	g_return_if_fail (GS_IS_MANAGER (manager));
+	g_return_if_fail (window != NULL);
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	gs_debug ("Handling window show");
+	manager_show_window (manager, window);
+}
+
+static void
+maybe_set_window_throttle (GSManager *manager,
+                           GSWindow  *window,
+                           gboolean   throttled)
+{
+	if (throttled)
+	{
+		manager_maybe_stop_job_for_window (manager, window);
+	}
+	else
+	{
+		manager_maybe_start_job_for_window (manager, window);
+	}
+}
+
+static void
+window_obscured_cb (GSWindow   *window,
+                    GParamSpec *pspec,
+                    GSManager  *manager)
+{
+	gboolean obscured;
+
+	obscured = gs_window_is_obscured (window);
+	gs_debug ("Handling window obscured: %s", obscured ? "obscured" : "unobscured");
+
+	maybe_set_window_throttle (manager, window, obscured);
+
+	if (! obscured)
+	{
+		gs_manager_request_unlock (manager);
+	}
+}
+
+static void
+handle_window_dialog_up (GSManager *manager,
+                         GSWindow  *window)
+{
+	GSList *l;
+
+	g_return_if_fail (manager != NULL);
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	gs_debug ("Handling dialog up");
+
+	g_signal_emit (manager, signals [AUTH_REQUEST_BEGIN], 0);
+
+	manager->priv->dialog_up = TRUE;
+	/* make all other windows insensitive to not get events */
+	for (l = manager->priv->windows; l; l = l->next)
+	{
+		if (l->data != window)
+		{
+			gtk_widget_set_sensitive (GTK_WIDGET (l->data), FALSE);
+		}
+	}
+
+	/* move devices grab so that dialog can be used;
+	   release the pointer grab while dialog is up so that
+	   the dialog can be used. We'll regrab it when the dialog goes down */
+	gs_debug ("Initiate pointer-less grab move to %p", window);
+	gs_grab_move_to_window (manager->priv->grab,
+	                        gs_window_get_gdk_window (window),
+	                        gs_window_get_display (window),
+	                        TRUE, FALSE);
+
+	if (! manager->priv->throttled)
+	{
+		gs_debug ("Suspending jobs");
+
+		manager_suspend_jobs (manager);
+	}
+}
+
+static void
+handle_window_dialog_down (GSManager *manager,
+                           GSWindow  *window)
+{
+	GSList *l;
+
+	g_return_if_fail (manager != NULL);
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	gs_debug ("Handling dialog down");
+
+	/* regrab pointer */
+	gs_grab_move_to_window (manager->priv->grab,
+	                        gs_window_get_gdk_window (window),
+	                        gs_window_get_display (window),
+	                        FALSE, FALSE);
+
+	/* make all windows sensitive to get events */
+	for (l = manager->priv->windows; l; l = l->next)
+	{
+		gtk_widget_set_sensitive (GTK_WIDGET (l->data), TRUE);
+	}
+
+	manager->priv->dialog_up = FALSE;
+
+	if (! manager->priv->throttled)
+	{
+		manager_resume_jobs (manager);
+	}
+
+	g_signal_emit (manager, signals [AUTH_REQUEST_END], 0);
+}
+
+static void
+window_dialog_up_changed_cb (GSWindow   *window,
+                             GParamSpec *pspec,
+                             GSManager  *manager)
+{
+	gboolean up;
+
+	up = gs_window_is_dialog_up (window);
+	gs_debug ("Handling window dialog up changed: %s", up ? "up" : "down");
+	if (up)
+	{
+		handle_window_dialog_up (manager, window);
+	}
+	else
+	{
+		handle_window_dialog_down (manager, window);
+	}
+}
+
+static gboolean
+window_activity_cb (GSWindow  *window,
+                    GSManager *manager)
+{
+	gboolean handled;
+
+	handled = gs_manager_request_unlock (manager);
+
+	return handled;
+}
+
+static void
+disconnect_window_signals (GSManager *manager,
+                           GSWindow  *window)
+{
+	g_signal_handlers_disconnect_by_func (window, window_deactivated_cb, manager);
+	g_signal_handlers_disconnect_by_func (window, window_activity_cb, manager);
+	g_signal_handlers_disconnect_by_func (window, window_show_cb, manager);
+	g_signal_handlers_disconnect_by_func (window, window_map_cb, manager);
+	g_signal_handlers_disconnect_by_func (window, window_map_event_cb, manager);
+	g_signal_handlers_disconnect_by_func (window, window_obscured_cb, manager);
+	g_signal_handlers_disconnect_by_func (window, window_dialog_up_changed_cb, manager);
+	g_signal_handlers_disconnect_by_func (window, window_unmap_cb, manager);
+	g_signal_handlers_disconnect_by_func (window, window_grab_broken_cb, manager);
+}
+
+static void
+window_destroyed_cb (GtkWindow *window,
+                     GSManager *manager)
+{
+	disconnect_window_signals (manager, GS_WINDOW (window));
+}
+
+static void
+connect_window_signals (GSManager *manager,
+                        GSWindow  *window)
+{
+	g_signal_connect_object (window, "destroy",
+	                         G_CALLBACK (window_destroyed_cb), manager, 0);
+	g_signal_connect_object (window, "activity",
+	                         G_CALLBACK (window_activity_cb), manager, 0);
+	g_signal_connect_object (window, "deactivated",
+	                         G_CALLBACK (window_deactivated_cb), manager, 0);
+	g_signal_connect_object (window, "show",
+	                         G_CALLBACK (window_show_cb), manager, G_CONNECT_AFTER);
+	g_signal_connect_object (window, "map",
+	                         G_CALLBACK (window_map_cb), manager, G_CONNECT_AFTER);
+	g_signal_connect_object (window, "map_event",
+	                         G_CALLBACK (window_map_event_cb), manager, G_CONNECT_AFTER);
+	g_signal_connect_object (window, "notify::obscured",
+	                         G_CALLBACK (window_obscured_cb), manager, G_CONNECT_AFTER);
+	g_signal_connect_object (window, "notify::dialog-up",
+	                         G_CALLBACK (window_dialog_up_changed_cb), manager, 0);
+	g_signal_connect_object (window, "unmap",
+	                         G_CALLBACK (window_unmap_cb), manager, G_CONNECT_AFTER);
+	g_signal_connect_object (window, "grab_broken_event",
+	                         G_CALLBACK (window_grab_broken_cb), manager, G_CONNECT_AFTER);
+}
+
+static void
+gs_manager_create_window_for_monitor (GSManager  *manager,
+                                      GdkMonitor *monitor)
+{
+	GSWindow    *window;
+	GdkRectangle rect;
+
+	gdk_monitor_get_geometry (monitor, &rect);
+
+	gs_debug ("Creating a window [%d,%d] (%dx%d)",
+	          rect.x, rect.y, rect.width, rect.height);
+
+	window = gs_window_new (monitor, manager->priv->lock_active);
+
+	gs_window_set_user_switch_enabled (window, manager->priv->user_switch_enabled);
+	gs_window_set_logout_enabled (window, manager->priv->logout_enabled);
+	gs_window_set_logout_timeout (window, manager->priv->logout_timeout);
+	gs_window_set_logout_command (window, manager->priv->logout_command);
+	gs_window_set_keyboard_enabled (window, manager->priv->keyboard_enabled);
+	gs_window_set_keyboard_command (window, manager->priv->keyboard_command);
+	gs_window_set_status_message (window, manager->priv->status_message);
+
+	connect_window_signals (manager, window);
+
+	manager->priv->windows = g_slist_append (manager->priv->windows, window);
+
+	if (manager->priv->active && !manager->priv->fading)
+	{
+		gtk_widget_show (GTK_WIDGET (window));
+	}
+}
+
+static void
+on_display_monitor_added (GdkDisplay *display,
+                          GdkMonitor *monitor,
+                          GSManager  *manager)
+{
+	GSList     *l;
+	int         n_monitors;
+
+	n_monitors = gdk_display_get_n_monitors (display);<--- Variable 'n_monitors' is assigned a value that is never used.
+
+	gs_debug ("Monitor added on display %s, now there are %d",
+	          gdk_display_get_name (display), n_monitors);
+
+	/* Tear down the unlock dialog in case we want to move it
+	 * to the new monitor
+	 */
+	l = manager->priv->windows;
+	while (l != NULL)
+	{
+		gs_window_cancel_unlock_request (GS_WINDOW (l->data));
+		l = l->next;
+	}
+
+	/* add a new window */
+	gs_manager_create_window_for_monitor (manager, monitor);
+
+	/* and put unlock dialog up whereever it's supposed to be */
+	gs_manager_request_unlock (manager);
+}
+
+static void
+on_display_monitor_removed (GdkDisplay *display,
+                            GdkMonitor *monitor,<--- Parameter 'monitor' can be declared with const
+                            GSManager  *manager)
+{
+	GSList     *l;
+	int         n_monitors;
+
+	n_monitors = gdk_display_get_n_monitors (display);<--- Variable 'n_monitors' is assigned a value that is never used.
+
+	gs_debug ("Monitor removed on display %s, now there are %d",
+	          gdk_display_get_name (display), n_monitors);
+
+	gdk_x11_grab_server ();
+
+	/* remove the now extra window */
+	l = manager->priv->windows;
+	while (l != NULL)
+	{
+		GdkDisplay *this_display;
+		GdkMonitor *this_monitor;
+		GSList     *next = l->next;
+
+		this_display = gs_window_get_display (GS_WINDOW (l->data));
+		this_monitor = gs_window_get_monitor (GS_WINDOW (l->data));
+		if (this_display == display && this_monitor == monitor)
+		{
+			manager_maybe_stop_job_for_window (manager,
+			                                   GS_WINDOW (l->data));
+			g_hash_table_remove (manager->priv->jobs, l->data);
+			gs_window_destroy (GS_WINDOW (l->data));
+			manager->priv->windows = g_slist_delete_link (manager->priv->windows, l);
+		}
+		l = next;
+	}
+
+	gdk_display_flush (display);
+	gdk_x11_ungrab_server ();
+}
+
+static void
+gs_manager_destroy_windows (GSManager *manager)
+{
+	GdkDisplay  *display;
+	GSList      *l;
+
+	g_return_if_fail (manager != NULL);
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	if (manager->priv->windows == NULL)
+	{
+		return;
+	}
+
+	display = gdk_display_get_default ();
+
+	g_signal_handlers_disconnect_by_func (display,
+	                                      on_display_monitor_removed,
+	                                      manager);
+	g_signal_handlers_disconnect_by_func (display,
+	                                      on_display_monitor_added,
+	                                      manager);
+
+	for (l = manager->priv->windows; l; l = l->next)
+	{
+		gs_window_destroy (l->data);
+	}
+	g_slist_free (manager->priv->windows);
+	manager->priv->windows = NULL;
+}
+
+static void
+gs_manager_finalize (GObject *object)
+{
+	GSManager *manager;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GS_IS_MANAGER (object));
+
+	manager = GS_MANAGER (object);
+
+	g_return_if_fail (manager->priv != NULL);
+
+	if (manager->priv->bg != NULL)
+	{
+		g_object_unref (manager->priv->bg);
+	}
+
+	free_themes (manager);
+	g_free (manager->priv->logout_command);
+	g_free (manager->priv->keyboard_command);
+	g_free (manager->priv->status_message);
+
+	remove_unfade_idle (manager);
+	remove_timers (manager);
+
+	gs_grab_release (manager->priv->grab, TRUE);
+
+	manager_stop_jobs (manager);
+
+	gs_manager_destroy_windows (manager);
+
+	manager->priv->active = FALSE;
+	manager->priv->activate_time = 0;
+	manager->priv->lock_enabled = FALSE;
+
+	g_object_unref (manager->priv->fade);
+	g_object_unref (manager->priv->grab);
+	g_object_unref (manager->priv->theme_manager);
+
+	G_OBJECT_CLASS (gs_manager_parent_class)->finalize (object);
+}
+
+static void
+gs_manager_create_windows_for_display (GSManager  *manager,
+                                       GdkDisplay *display)
+{
+	int n_monitors;
+	int i;
+
+	g_return_if_fail (manager != NULL);
+	g_return_if_fail (GS_IS_MANAGER (manager));
+	g_return_if_fail (GDK_IS_DISPLAY (display));
+
+	g_object_ref (manager);
+	g_object_ref (display);
+
+	n_monitors = gdk_display_get_n_monitors (display);
+
+	gs_debug ("Creating %d windows for display %s",
+	          n_monitors, gdk_display_get_name (display));
+
+	for (i = 0; i < n_monitors; i++)
+	{
+		GdkMonitor *mon = gdk_display_get_monitor (display, i);
+		gs_manager_create_window_for_monitor (manager, mon);
+	}
+
+	g_object_unref (display);
+	g_object_unref (manager);
+}
+
+static void
+gs_manager_create_windows (GSManager *manager)
+{
+	GdkDisplay  *display;
+
+	g_return_if_fail (manager != NULL);
+	g_return_if_fail (GS_IS_MANAGER (manager));
+
+	g_assert (manager->priv->windows == NULL);
+
+	display = gdk_display_get_default ();
+	g_signal_connect (display, "monitor-added",
+	                  G_CALLBACK (on_display_monitor_added),
+	                  manager);
+	g_signal_connect (display, "monitor-removed",
+	                  G_CALLBACK (on_display_monitor_removed),
+	                  manager);
+
+	gs_manager_create_windows_for_display (manager, display);
+}
+
+GSManager *
+gs_manager_new (void)
+{
+	GObject *manager;
+
+	manager = g_object_new (GS_TYPE_MANAGER, NULL);
+
+	return GS_MANAGER (manager);
+}
+
+static void
+show_windows (GSList *windows)
+{
+	GSList *l;
+
+	for (l = windows; l; l = l->next)
+	{
+		gtk_widget_show (GTK_WIDGET (l->data));
+	}
+}
+
+static void
+remove_job (GSJob *job)
+{
+	if (job == NULL)
+	{
+		return;
+	}
+
+	gs_job_stop (job);
+	g_object_unref (job);
+}
+
+static void
+fade_done_cb (GSFade    *fade,
+              GSManager *manager)
+{
+	gs_debug ("fade completed, showing windows");
+	show_windows (manager->priv->windows);
+	manager->priv->fading = FALSE;
+}
+
+static gboolean
+gs_manager_activate (GSManager *manager)
+{
+	gboolean    do_fade;
+	gboolean    res;
+
+	g_return_val_if_fail (manager != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE);
+
+	if (manager->priv->active)
+	{
+		gs_debug ("Trying to activate manager when already active");
+		return FALSE;
+	}
+
+	res = gs_grab_grab_root (manager->priv->grab, FALSE, FALSE);
+	if (! res)
+	{
+		return FALSE;
+	}
+
+	if (manager->priv->windows == NULL)
+	{
+		gs_manager_create_windows (GS_MANAGER (manager));
+	}
+
+	manager->priv->jobs = g_hash_table_new_full (g_direct_hash,
+	                      g_direct_equal,
+	                      NULL,
+	                      (GDestroyNotify)remove_job);
+
+	manager->priv->active = TRUE;
+
+	/* fade to black and show windows */
+	do_fade = FALSE;
+	if (do_fade)
+	{
+		manager->priv->fading = TRUE;
+		gs_debug ("fading out");
+		gs_fade_async (manager->priv->fade,
+		               FADE_TIMEOUT,
+		               (GSFadeDoneFunc)fade_done_cb,
+		               manager);
+
+		while (manager->priv->fading)
+		{
+			gtk_main_iteration ();
+		}
+	}
+	else
+	{
+		show_windows (manager->priv->windows);
+	}
+
+	return TRUE;
+}
+
+static gboolean
+gs_manager_deactivate (GSManager *manager)
+{
+	g_return_val_if_fail (manager != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE);
+
+	if (! manager->priv->active)
+	{
+		gs_debug ("Trying to deactivate a screensaver that is not active");
+		return FALSE;
+	}
+
+	remove_unfade_idle (manager);
+	gs_fade_reset (manager->priv->fade);
+	remove_timers (manager);
+
+	gs_grab_release (manager->priv->grab, TRUE);
+
+	manager_stop_jobs (manager);
+
+	gs_manager_destroy_windows (manager);
+
+	/* reset state */
+	manager->priv->active = FALSE;
+	manager->priv->activate_time = 0;
+	manager->priv->lock_active = FALSE;
+	manager->priv->dialog_up = FALSE;
+	manager->priv->fading = FALSE;
+
+	return TRUE;
+}
+
+gboolean
+gs_manager_set_active (GSManager *manager,
+                       gboolean   active)
+{
+	gboolean res;
+
+	if (active)
+	{
+		res = gs_manager_activate (manager);
+	}
+	else
+	{
+		res = gs_manager_deactivate (manager);
+	}
+
+	return res;
+}
+
+gboolean
+gs_manager_get_active (GSManager *manager)
+{
+	g_return_val_if_fail (manager != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE);
+
+	return manager->priv->active;
+}
+
+gboolean
+gs_manager_request_unlock (GSManager *manager)
+{
+	GSWindow *window;
+
+	g_return_val_if_fail (manager != NULL, FALSE);
+	g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE);
+
+	if (! manager->priv->active)
+	{
+		gs_debug ("Request unlock but manager is not active");
+		return FALSE;
+	}
+
+	if (manager->priv->dialog_up)
+	{
+		gs_debug ("Request unlock but dialog is already up");
+		return FALSE;
+	}
+
+	if (manager->priv->fading)
+	{
+		gs_debug ("Request unlock so finishing fade");
+		gs_fade_finish (manager->priv->fade);
+	}
+
+	if (manager->priv->windows == NULL)
+	{
+		gs_debug ("We don't have any windows!");
+		return FALSE;
+	}
+
+	/* Find the GSWindow that contains the pointer */
+	window = find_window_at_pointer (manager);
+        apply_background_to_window (manager, window);
+	gs_window_request_unlock (window);
+
+	return TRUE;
+}
+
+void
+gs_manager_cancel_unlock_request (GSManager *manager)
+{
+	GSList *l;
+	for (l = manager->priv->windows; l; l = l->next)
+	{
+		gs_window_cancel_unlock_request (l->data);
+	}
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/14.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/14.html new file mode 100644 index 0000000..31acee0 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/14.html @@ -0,0 +1,1141 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib-object.h>
+#include <matemenu-tree.h>
+
+#include "gs-theme-manager.h"
+#include "gs-debug.h"
+
+static void     gs_theme_manager_finalize   (GObject             *object);
+
+struct _GSThemeInfo
+{
+	char  *name;
+	char  *exec;
+	char  *file_id;
+	guint  refcount;
+};
+
+struct GSThemeManagerPrivate
+{
+	MateMenuTree *menu_tree;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSThemeManager, gs_theme_manager, G_TYPE_OBJECT)
+
+static gpointer theme_manager_object = NULL;
+
+static const char *known_engine_locations [] =
+{
+	SAVERDIR,
+#ifdef XSCREENSAVER_HACK_DIR
+	XSCREENSAVER_HACK_DIR,<--- Skipping configuration 'XSCREENSAVER_HACK_DIR' since the value of 'XSCREENSAVER_HACK_DIR' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly.
+#endif
+	LIBEXECDIR "/xscreensaver",
+	"/usr/libexec/xscreensaver",
+	"/usr/lib/xscreensaver",
+	NULL
+};
+
+/* Returns the full path to the queried command */
+static char *
+find_command (const char *command)
+{
+	int i;
+
+	if (g_path_is_absolute (command))
+	{
+		char *dirname;
+
+		dirname = g_path_get_dirname (command);
+		for (i = 0; known_engine_locations [i]; i++)
+		{
+			if (strcmp (dirname, known_engine_locations [i]) == 0)
+			{
+				if (g_file_test (command, G_FILE_TEST_IS_EXECUTABLE)
+				        && ! g_file_test (command, G_FILE_TEST_IS_DIR))
+				{
+					g_free (dirname);
+					return g_strdup (command);
+				}
+			}
+		}
+		g_free (dirname);
+	}
+	else
+	{
+		for (i = 0; known_engine_locations [i]; i++)
+		{
+			char *path;
+
+			path = g_build_filename (known_engine_locations [i], command, NULL);
+
+			if (g_file_test (path, G_FILE_TEST_IS_EXECUTABLE)
+			        && ! g_file_test (path, G_FILE_TEST_IS_DIR))
+			{
+				return path;
+			}
+
+			g_free (path);
+		}
+	}
+
+	return NULL;
+}
+
+static gboolean
+check_command (const char *command)
+{
+	char *path;
+	char **argv;
+
+	g_return_val_if_fail (command != NULL, FALSE);
+
+	g_shell_parse_argv (command, NULL, &argv, NULL);
+	path = find_command (argv [0]);
+	g_strfreev (argv);
+
+	if (path != NULL)
+	{
+		g_free (path);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+add_known_engine_locations_to_path (void)
+{
+	static gboolean already_added;
+	int      i;
+	GString *str;
+
+	/* We only want to add the items to the path once */
+	if (already_added)
+	{
+		return;
+	}
+
+	already_added = TRUE;
+
+	/* TODO: set a default PATH ? */
+
+	str = g_string_new (g_getenv ("PATH"));
+	for (i = 0; known_engine_locations [i]; i++)
+	{
+		/* TODO: check that permissions are safe */
+		if (g_file_test (known_engine_locations [i], G_FILE_TEST_IS_DIR))
+		{
+			g_string_append_printf (str, ":%s", known_engine_locations [i]);
+		}
+	}
+
+	g_setenv ("PATH", str->str, TRUE);
+	g_string_free (str, TRUE);
+}
+
+GSThemeInfo *
+gs_theme_info_ref (GSThemeInfo *info)
+{
+	g_return_val_if_fail (info != NULL, NULL);
+	g_return_val_if_fail (info->refcount > 0, NULL);
+
+	info->refcount++;
+
+	return info;
+}
+
+void
+gs_theme_info_unref (GSThemeInfo *info)
+{
+	g_return_if_fail (info != NULL);
+	g_return_if_fail (info->refcount > 0);
+
+	if (--info->refcount == 0)
+	{
+		g_free (info->name);
+		g_free (info->exec);
+		g_free (info->file_id);
+
+		g_free (info);
+	}
+}
+
+const char *
+gs_theme_info_get_id (GSThemeInfo *info)
+{
+	g_return_val_if_fail (info != NULL, NULL);
+
+	return info->file_id;
+}
+
+const char *
+gs_theme_info_get_name (GSThemeInfo *info)
+{
+	g_return_val_if_fail (info != NULL, NULL);
+
+	return info->name;
+}
+
+const char *
+gs_theme_info_get_exec (GSThemeInfo *info)
+{
+	const char *exec;
+
+	g_return_val_if_fail (info != NULL, NULL);
+
+	if (check_command (info->exec))
+	{
+		exec = info->exec;
+	}
+	else
+	{
+		exec = NULL;
+	}
+
+	return exec;
+}
+
+static GSThemeInfo *
+gs_theme_info_new_from_matemenu_tree_entry (MateMenuTreeEntry *entry)
+{
+	GSThemeInfo *info;
+	const char     *str;
+	char           *pos;
+	GDesktopAppInfo *ginfo;
+
+	info = g_new0 (GSThemeInfo, 1);
+	ginfo = matemenu_tree_entry_get_app_info (entry);
+
+	info->refcount = 1;
+	info->name     = g_strdup (g_app_info_get_name(G_APP_INFO(ginfo)));
+	info->exec     = g_strdup (g_app_info_get_commandline(G_APP_INFO(ginfo)));
+
+	/* remove the .desktop suffix */
+	str = matemenu_tree_entry_get_desktop_file_id (entry);
+	pos = g_strrstr (str, ".desktop");
+	if (pos)
+	{
+		info->file_id = g_strndup (str, pos - str);
+	}
+	else
+	{
+		info->file_id  = g_strdup (str);
+	}
+
+	return info;
+}
+
+static GSThemeInfo *
+find_info_for_id (MateMenuTree  *tree,
+                  const char *id)
+{
+	GSThemeInfo     *info;
+	MateMenuTreeDirectory *root;
+	MateMenuTreeIter *iter;
+	MateMenuTreeItemType type;
+
+	root = matemenu_tree_get_root_directory (tree);
+	if (root == NULL)
+	{
+		return NULL;
+	}
+
+	info = NULL;
+	iter = matemenu_tree_directory_iter (root);
+	while ((type = matemenu_tree_iter_next (iter)) != MATEMENU_TREE_ITEM_INVALID) {
+		if (info == NULL && type == MATEMENU_TREE_ITEM_ENTRY) {
+			MateMenuTreeEntry *entry;
+			const char     *file_id;
+
+			entry = matemenu_tree_iter_get_entry(iter);
+			file_id = matemenu_tree_entry_get_desktop_file_id (entry);
+			if (file_id && id && strcmp (file_id, id) == 0)
+			{
+				info = gs_theme_info_new_from_matemenu_tree_entry (entry);
+			}
+			matemenu_tree_item_unref (entry);
+		}
+	}
+	matemenu_tree_iter_unref (iter);
+	matemenu_tree_item_unref (root);
+	return info;
+}
+
+GSThemeInfo *
+gs_theme_manager_lookup_theme_info (GSThemeManager *theme_manager,
+                                    const char     *name)
+{
+	GSThemeInfo *info;
+	char        *id;
+
+	g_return_val_if_fail (GS_IS_THEME_MANAGER (theme_manager), NULL);
+	g_return_val_if_fail (name != NULL, NULL);
+
+	id = g_strdup_printf ("%s.desktop", name);
+	info = find_info_for_id (theme_manager->priv->menu_tree, id);
+	g_free (id);
+
+	return info;
+}
+
+static void
+theme_prepend_entry (GSList         **parent_list,
+                     MateMenuTreeEntry  *entry,
+                     const char      *filename)
+{
+	GSThemeInfo *info;
+
+	info = gs_theme_info_new_from_matemenu_tree_entry (entry);
+
+	*parent_list = g_slist_prepend (*parent_list, info);
+}
+
+static void
+make_theme_list (GSList             **parent_list,
+                 MateMenuTreeDirectory  *directory,
+                 const char          *filename)
+{
+	MateMenuTreeIter *iter;
+	MateMenuTreeItemType type;
+
+	iter = matemenu_tree_directory_iter (directory);
+	while ((type = matemenu_tree_iter_next (iter)) != MATEMENU_TREE_ITEM_INVALID) {
+		if (type == MATEMENU_TREE_ITEM_ENTRY) {
+			MateMenuTreeEntry *item;
+			item = matemenu_tree_iter_get_entry (iter);
+			theme_prepend_entry (parent_list, (MateMenuTreeEntry*)item, filename);
+			matemenu_tree_item_unref (item);
+		}
+	}
+	matemenu_tree_iter_unref (iter);
+	*parent_list = g_slist_reverse (*parent_list);
+}
+
+GSList *
+gs_theme_manager_get_info_list (GSThemeManager *theme_manager)
+{
+	GSList             *l = NULL;
+	MateMenuTreeDirectory *root;
+
+	g_return_val_if_fail (GS_IS_THEME_MANAGER (theme_manager), NULL);
+
+	root = matemenu_tree_get_root_directory (theme_manager->priv->menu_tree);
+
+	if (root != NULL)
+	{
+		make_theme_list (&l, root, "mate-screensavers.menu");
+		matemenu_tree_item_unref (root);
+	}
+
+	return l;
+}
+
+static void
+gs_theme_manager_class_init (GSThemeManagerClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = gs_theme_manager_finalize;
+}
+
+static MateMenuTree *
+get_themes_tree (void)
+{
+	MateMenuTree *themes_tree = NULL;
+	GError *error = NULL;
+
+	/* we only need to add the locations to the path once
+	   and since this is only run once we'll do it here */
+	add_known_engine_locations_to_path ();
+
+	themes_tree = matemenu_tree_new ("mate-screensavers.menu", MATEMENU_TREE_FLAGS_NONE);
+	if (!matemenu_tree_load_sync (themes_tree, &error)) {
+		g_debug("Load matemenu tree got error: %s\n", error->message);
+		g_error_free(error);
+		g_object_unref(themes_tree);
+		return NULL;
+	}
+
+	return themes_tree;
+}
+
+static void
+on_applications_changed (MateMenuTree *menu_tree)
+{
+	GError *error = NULL;
+
+	if (!matemenu_tree_load_sync (menu_tree, &error)) {
+		g_debug ("Load matemenu tree got error: %s\n", error->message);
+		g_error_free (error);
+	}
+}
+
+static void
+gs_theme_manager_init (GSThemeManager *theme_manager)
+{
+	theme_manager->priv = gs_theme_manager_get_instance_private (theme_manager);
+
+	theme_manager->priv->menu_tree = get_themes_tree ();
+	g_signal_connect (theme_manager->priv->menu_tree, "changed",
+	                  G_CALLBACK (on_applications_changed),
+	                  NULL);
+}
+
+static void
+gs_theme_manager_finalize (GObject *object)
+{
+	GSThemeManager *theme_manager;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GS_IS_THEME_MANAGER (object));
+
+	theme_manager = GS_THEME_MANAGER (object);
+
+	g_return_if_fail (theme_manager->priv != NULL);
+
+	if (theme_manager->priv->menu_tree != NULL)
+	{
+		g_object_unref(theme_manager->priv->menu_tree);
+	}
+
+	G_OBJECT_CLASS (gs_theme_manager_parent_class)->finalize (object);
+}
+
+GSThemeManager *
+gs_theme_manager_new (void)
+{
+	if (theme_manager_object)
+	{
+		g_object_ref (theme_manager_object);
+	}
+	else
+	{
+		theme_manager_object = g_object_new (GS_TYPE_THEME_MANAGER, NULL);
+		g_object_add_weak_pointer (theme_manager_object,
+		                           (gpointer *) &theme_manager_object);
+	}
+
+	return GS_THEME_MANAGER (theme_manager_object);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/15.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/15.html new file mode 100644 index 0000000..9042177 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/15.html @@ -0,0 +1,1587 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2008      Red Hat, Inc.
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <gdk/gdkx.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+
+#include "gs-watcher.h"
+#include "gs-marshal.h"
+#include "gs-debug.h"
+
+static void     gs_watcher_finalize   (GObject        *object);
+
+static gboolean watchdog_timer        (GSWatcher      *watcher);
+
+struct GSWatcherPrivate
+{
+	/* settings */
+	guint           enabled : 1;
+	guint           delta_notice_timeout;
+
+	/* state */
+	guint           active : 1;
+	guint           idle : 1;
+	guint           idle_notice : 1;
+
+	guint           idle_id;
+	char           *status_message;
+
+	DBusGProxy     *presence_proxy;
+	guint           watchdog_timer_id;
+};
+
+enum
+{
+    PROP_0,
+    PROP_STATUS_MESSAGE
+};
+
+enum
+{
+    IDLE_CHANGED,
+    IDLE_NOTICE_CHANGED,
+    LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSWatcher, gs_watcher, G_TYPE_OBJECT)
+
+static void
+remove_watchdog_timer (GSWatcher *watcher)
+{
+	if (watcher->priv->watchdog_timer_id != 0)
+	{
+		g_source_remove (watcher->priv->watchdog_timer_id);
+		watcher->priv->watchdog_timer_id = 0;
+	}
+}
+
+static void
+add_watchdog_timer (GSWatcher *watcher,
+                    guint      timeout)
+{
+	watcher->priv->watchdog_timer_id = g_timeout_add (timeout,
+	                                                  (GSourceFunc)watchdog_timer,
+	                                                  watcher);
+}
+
+static void
+gs_watcher_get_property (GObject    *object,
+                         guint       prop_id,
+                         GValue     *value,
+                         GParamSpec *pspec)
+{
+	GSWatcher *self;
+
+	self = GS_WATCHER (object);
+
+	switch (prop_id)
+	{
+	case PROP_STATUS_MESSAGE:
+		g_value_set_string (value, self->priv->status_message);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+set_status_text (GSWatcher  *watcher,
+                 const char *text)
+{
+	g_free (watcher->priv->status_message);
+
+	watcher->priv->status_message = g_strdup (text);
+	g_object_notify (G_OBJECT (watcher), "status-message");
+}
+
+static void
+gs_watcher_set_property (GObject          *object,
+                         guint             prop_id,
+                         const GValue     *value,
+                         GParamSpec       *pspec)
+{
+	GSWatcher *self;
+
+	self = GS_WATCHER (object);
+
+	switch (prop_id)
+	{
+	case PROP_STATUS_MESSAGE:
+		set_status_text (self, g_value_get_string (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gs_watcher_class_init (GSWatcherClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = gs_watcher_finalize;
+	object_class->get_property = gs_watcher_get_property;
+	object_class->set_property = gs_watcher_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_STATUS_MESSAGE,
+	                                 g_param_spec_string ("status-message",
+	                                         NULL,
+	                                         NULL,
+	                                         NULL,
+	                                         G_PARAM_READWRITE));
+
+	signals [IDLE_CHANGED] =
+	    g_signal_new ("idle-changed",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSWatcherClass, idle_changed),
+	                  NULL,
+	                  NULL,
+	                  gs_marshal_BOOLEAN__BOOLEAN,
+	                  G_TYPE_BOOLEAN,
+	                  1, G_TYPE_BOOLEAN);
+	signals [IDLE_NOTICE_CHANGED] =
+	    g_signal_new ("idle-notice-changed",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSWatcherClass, idle_notice_changed),
+	                  NULL,
+	                  NULL,
+	                  gs_marshal_BOOLEAN__BOOLEAN,
+	                  G_TYPE_BOOLEAN,
+	                  1, G_TYPE_BOOLEAN);
+}
+
+static gboolean
+_gs_watcher_set_session_idle_notice (GSWatcher *watcher,
+                                     gboolean   in_effect)
+{
+	gboolean res;
+
+	res = FALSE;
+
+	if (in_effect != watcher->priv->idle_notice)
+	{
+
+		g_signal_emit (watcher, signals [IDLE_NOTICE_CHANGED], 0, in_effect, &res);
+		if (res)
+		{
+			gs_debug ("Changing idle notice state: %d", in_effect);
+
+			watcher->priv->idle_notice = (in_effect != FALSE);
+		}
+		else
+		{
+			gs_debug ("Idle notice signal not handled: %d", in_effect);
+		}
+	}
+
+	return res;
+}
+
+static gboolean
+_gs_watcher_set_session_idle (GSWatcher *watcher,
+                              gboolean   is_idle)
+{
+	gboolean res;
+
+	res = FALSE;
+
+	if (is_idle != watcher->priv->idle)
+	{
+
+		g_signal_emit (watcher, signals [IDLE_CHANGED], 0, is_idle, &res);
+		if (res)
+		{
+			gs_debug ("Changing idle state: %d", is_idle);
+
+			watcher->priv->idle = (is_idle != FALSE);
+		}
+		else
+		{
+			gs_debug ("Idle changed signal not handled: %d", is_idle);
+		}
+	}
+
+	return res;
+}
+
+gboolean
+gs_watcher_get_active (GSWatcher *watcher)
+{
+	gboolean active;
+
+	g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE);
+
+	active = watcher->priv->active;
+
+	return active;
+}
+
+static void
+_gs_watcher_reset_state (GSWatcher *watcher)
+{
+	watcher->priv->idle = FALSE;
+	watcher->priv->idle_notice = FALSE;
+}
+
+static gboolean
+_gs_watcher_set_active_internal (GSWatcher *watcher,
+                                 gboolean   active)
+{
+	if (active != watcher->priv->active)
+	{
+		/* reset state */
+		_gs_watcher_reset_state (watcher);
+
+		watcher->priv->active = (active != FALSE);
+	}
+
+	return TRUE;
+}
+
+gboolean
+gs_watcher_set_active (GSWatcher *watcher,
+                       gboolean   active)
+{
+	g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE);
+
+	gs_debug ("turning watcher: %s", active ? "ON" : "OFF");
+
+	if (watcher->priv->active == active)
+	{
+		gs_debug ("Idle detection is already %s",
+		          active ? "active" : "inactive");
+		return FALSE;
+	}
+
+	if (! watcher->priv->enabled)
+	{
+		gs_debug ("Idle detection is disabled, cannot activate");
+		return FALSE;
+	}
+
+	return _gs_watcher_set_active_internal (watcher, active);
+}
+
+gboolean
+gs_watcher_set_enabled (GSWatcher *watcher,
+                        gboolean   enabled)
+{
+	g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE);
+
+	if (watcher->priv->enabled != enabled)
+	{
+		gboolean is_active = gs_watcher_get_active (watcher);
+
+		watcher->priv->enabled = (enabled != FALSE);
+
+		/* if we are disabling the watcher and we are
+		   active shut it down */
+		if (! enabled && is_active)
+		{
+			_gs_watcher_set_active_internal (watcher, FALSE);
+		}
+	}
+
+	return TRUE;
+}
+
+gboolean
+gs_watcher_get_enabled (GSWatcher *watcher)
+{
+	gboolean enabled;
+
+	g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE);
+
+	enabled = watcher->priv->enabled;
+
+	return enabled;
+}
+
+static gboolean
+on_idle_timeout (GSWatcher *watcher)
+{
+	gboolean res;
+
+	res = _gs_watcher_set_session_idle (watcher, TRUE);
+
+	_gs_watcher_set_session_idle_notice (watcher, FALSE);
+
+	/* try again if we failed i guess */
+	return !res;
+}
+
+static void
+set_status (GSWatcher *watcher,
+            guint      status)
+{
+	gboolean is_idle;
+
+	if (! watcher->priv->active)
+	{
+		gs_debug ("GSWatcher: not active, ignoring status changes");
+		return;
+	}
+
+	is_idle = (status == 3);
+
+	if (!is_idle && !watcher->priv->idle_notice)
+	{
+		/* no change in idleness */
+		return;
+	}
+
+	if (is_idle)
+	{
+		_gs_watcher_set_session_idle_notice (watcher, is_idle);
+		/* queue an activation */
+		if (watcher->priv->idle_id > 0)
+		{
+			g_source_remove (watcher->priv->idle_id);
+		}
+		watcher->priv->idle_id = g_timeout_add (watcher->priv->delta_notice_timeout,
+		                                        (GSourceFunc)on_idle_timeout,
+		                                        watcher);
+	}
+	else
+	{
+		/* cancel notice too */
+		if (watcher->priv->idle_id > 0)
+		{
+			g_source_remove (watcher->priv->idle_id);
+			watcher->priv->idle_id = 0;
+		}
+		_gs_watcher_set_session_idle (watcher, FALSE);
+		_gs_watcher_set_session_idle_notice (watcher, FALSE);
+	}
+}
+
+static void
+on_presence_status_changed (DBusGProxy    *presence_proxy,
+                            guint          status,
+                            GSWatcher     *watcher)
+{
+	set_status (watcher, status);
+}
+
+static void
+on_presence_status_text_changed (DBusGProxy    *presence_proxy,
+                                 const char    *status_text,
+                                 GSWatcher     *watcher)
+{
+	set_status_text (watcher, status_text);
+}
+
+static gboolean
+connect_presence_watcher (GSWatcher *watcher)
+{
+	DBusGConnection   *bus;
+	GError            *error;
+	gboolean           ret;
+
+	ret = FALSE;
+
+	error = NULL;
+	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	if (bus == NULL)
+	{
+		g_warning ("Unable to get session bus: %s", error->message);
+		g_error_free (error);
+		goto done;
+	}
+
+	error = NULL;
+	watcher->priv->presence_proxy = dbus_g_proxy_new_for_name_owner (bus,
+	                                "org.gnome.SessionManager",
+	                                "/org/gnome/SessionManager/Presence",
+	                                "org.gnome.SessionManager.Presence",
+	                                &error);
+	if (watcher->priv->presence_proxy != NULL)
+	{
+		DBusGProxy *proxy;
+
+		dbus_g_proxy_add_signal (watcher->priv->presence_proxy,
+		                         "StatusChanged",
+		                         G_TYPE_UINT,
+		                         G_TYPE_INVALID);
+		dbus_g_proxy_connect_signal (watcher->priv->presence_proxy,
+		                             "StatusChanged",
+		                             G_CALLBACK (on_presence_status_changed),
+		                             watcher,
+		                             NULL);
+		dbus_g_proxy_add_signal (watcher->priv->presence_proxy,
+		                         "StatusTextChanged",
+		                         G_TYPE_STRING,
+		                         G_TYPE_INVALID);
+		dbus_g_proxy_connect_signal (watcher->priv->presence_proxy,
+		                             "StatusTextChanged",
+		                             G_CALLBACK (on_presence_status_text_changed),
+		                             watcher,
+		                             NULL);
+
+		proxy = dbus_g_proxy_new_from_proxy (watcher->priv->presence_proxy,
+		                                     "org.freedesktop.DBus.Properties",
+		                                     "/org/gnome/SessionManager/Presence");
+		if (proxy != NULL)
+		{
+			guint       status;
+			const char *status_text;
+			GValue      value = { 0, };
+
+			status = 0;
+			status_text = NULL;
+
+			error = NULL;
+			dbus_g_proxy_call (proxy,
+			                   "Get",
+			                   &error,
+			                   G_TYPE_STRING, "org.gnome.SessionManager.Presence",
+			                   G_TYPE_STRING, "status",
+			                   G_TYPE_INVALID,
+			                   G_TYPE_VALUE, &value,
+			                   G_TYPE_INVALID);
+
+			if (error != NULL)
+			{
+				g_warning ("Couldn't get presence status: %s", error->message);
+				g_error_free (error);
+				goto done;
+			}
+			else
+			{
+				status = g_value_get_uint (&value);
+			}
+
+			g_value_unset (&value);
+
+			error = NULL;
+			dbus_g_proxy_call (proxy,
+			                   "Get",
+			                   &error,
+			                   G_TYPE_STRING, "org.gnome.SessionManager.Presence",
+			                   G_TYPE_STRING, "status-text",
+			                   G_TYPE_INVALID,
+			                   G_TYPE_VALUE, &value,
+			                   G_TYPE_INVALID);
+
+			if (error != NULL)
+			{
+				g_warning ("Couldn't get presence status text: %s", error->message);
+				g_error_free (error);
+			}
+			else
+			{
+				status_text = g_value_get_string (&value);
+			}
+
+			set_status (watcher, status);
+			set_status_text (watcher, status_text);
+		}
+	}
+	else
+	{
+		g_warning ("Failed to get session presence proxy: %s", error->message);
+		g_error_free (error);
+		goto done;
+	}
+
+	ret = TRUE;
+
+done:
+	return ret;
+}
+
+static void
+gs_watcher_init (GSWatcher *watcher)
+{
+	watcher->priv = gs_watcher_get_instance_private (watcher);
+
+	watcher->priv->enabled = TRUE;
+	watcher->priv->active = FALSE;
+
+	connect_presence_watcher (watcher);
+
+	/* time before idle signal to send notice signal */
+	watcher->priv->delta_notice_timeout = 10000;
+
+	add_watchdog_timer (watcher, 600000);
+}
+
+static void
+gs_watcher_finalize (GObject *object)
+{
+	GSWatcher *watcher;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GS_IS_WATCHER (object));
+
+	watcher = GS_WATCHER (object);
+
+	g_return_if_fail (watcher->priv != NULL);
+
+	remove_watchdog_timer (watcher);
+
+	if (watcher->priv->idle_id > 0)
+	{
+		g_source_remove (watcher->priv->idle_id);
+		watcher->priv->idle_id = 0;
+	}
+
+	watcher->priv->active = FALSE;
+
+	if (watcher->priv->presence_proxy != NULL)
+	{
+		g_object_unref (watcher->priv->presence_proxy);
+	}
+
+	g_free (watcher->priv->status_message);
+
+	G_OBJECT_CLASS (gs_watcher_parent_class)->finalize (object);
+}
+
+/* Figuring out what the appropriate XSetScreenSaver() parameters are
+   (one wouldn't expect this to be rocket science.)
+*/
+static void
+disable_builtin_screensaver (GSWatcher *watcher,
+                             gboolean   unblank_screen)
+{
+	int current_server_timeout, current_server_interval;
+	int current_prefer_blank,   current_allow_exp;
+	int desired_server_timeout, desired_server_interval;
+	int desired_prefer_blank,   desired_allow_exp;
+
+	XGetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+	                 &current_server_timeout,
+	                 &current_server_interval,
+	                 &current_prefer_blank,
+	                 &current_allow_exp);
+
+	desired_server_timeout  = current_server_timeout;<--- desired_server_timeout is assigned
+	desired_server_interval = current_server_interval;<--- desired_server_interval is assigned
+	desired_prefer_blank    = current_prefer_blank;<--- desired_prefer_blank is assigned 'current_prefer_blank' here.
+	desired_allow_exp       = current_allow_exp;<--- desired_allow_exp is assigned
+
+	desired_server_interval = 0;<--- desired_server_interval is overwritten
+
+	/* I suspect (but am not sure) that DontAllowExposures might have
+	   something to do with powering off the monitor as well, at least
+	   on some systems that don't support XDPMS?  Who know... */
+	desired_allow_exp = AllowExposures;<--- desired_allow_exp is overwritten
+
+	/* When we're not using an extension, set the server-side timeout to 0,
+	   so that the server never gets involved with screen blanking, and we
+	   do it all ourselves.  (However, when we *are* using an extension,
+	   we tell the server when to notify us, and rather than blanking the
+	   screen, the server will send us an X event telling us to blank.)
+	*/
+	desired_server_timeout = 0;<--- desired_server_timeout is overwritten
+
+	if (desired_server_timeout     != current_server_timeout
+	        || desired_server_interval != current_server_interval
+	        || desired_prefer_blank    != current_prefer_blank<--- Condition 'desired_prefer_blank!=current_prefer_blank' is always false
+	        || desired_allow_exp       != current_allow_exp)
+	{
+
+		gs_debug ("disabling server builtin screensaver:"
+		          " (xset s %d %d; xset s %s; xset s %s)",
+		          desired_server_timeout,
+		          desired_server_interval,
+		          (desired_prefer_blank ? "blank" : "noblank"),
+		          (desired_allow_exp ? "expose" : "noexpose"));
+
+		XSetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+		                 desired_server_timeout,
+		                 desired_server_interval,
+		                 desired_prefer_blank,
+		                 desired_allow_exp);
+
+		XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE);
+	}
+
+	if (unblank_screen)
+	{
+		/* Turn off the server builtin saver if it is now running. */
+		XForceScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), ScreenSaverReset);
+	}
+}
+
+/* This timer goes off every few minutes, whether the user is idle or not,
+   to try and clean up anything that has gone wrong.
+
+   It calls disable_builtin_screensaver() so that if xset has been used,
+   or some other program (like xlock) has messed with the XSetScreenSaver()
+   settings, they will be set back to sensible values (if a server extension
+   is in use, messing with xlock can cause the screensaver to never get a wakeup
+   event, and could cause monitor power-saving to occur, and all manner of
+   heinousness.)
+
+ */
+
+static gboolean
+watchdog_timer (GSWatcher *watcher)
+{
+
+	disable_builtin_screensaver (watcher, FALSE);
+
+	return TRUE;
+}
+
+GSWatcher *
+gs_watcher_new (void)
+{
+	GSWatcher *watcher;
+
+	watcher = g_object_new (GS_TYPE_WATCHER,
+	                        NULL);
+
+	return GS_WATCHER (watcher);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/16.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/16.html new file mode 100644 index 0000000..963e439 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/16.html @@ -0,0 +1,5425 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
+2539
+2540
+2541
+2542
+2543
+2544
+2545
+2546
+2547
+2548
+2549
+2550
+2551
+2552
+2553
+2554
+2555
+2556
+2557
+2558
+2559
+2560
+2561
+2562
+2563
+2564
+2565
+2566
+2567
+2568
+2569
+2570
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2008 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <string.h>
+
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkx.h>
+
+#include "gs-window.h"
+#include "gs-marshal.h"
+#include "subprocs.h"
+#include "gs-debug.h"
+
+#ifdef HAVE_SHAPE_EXT
+#include <X11/extensions/shape.h>
+#endif
+
+static void gs_window_finalize   (GObject       *object);
+
+static gboolean popup_dialog_idle (gpointer data);
+static void gs_window_dialog_finish (GSWindow *window);
+static void remove_command_watches (GSWindow *window);
+
+enum
+{
+    DIALOG_RESPONSE_CANCEL,
+    DIALOG_RESPONSE_OK
+};
+
+#define MAX_QUEUED_EVENTS 16
+#define INFO_BAR_SECONDS 30
+#define MATE_SCREENSAVER_DIALOG_PATH LIBEXECDIR "/mate-screensaver-dialog"
+
+struct GSWindowPrivate
+{
+	GdkMonitor *monitor;
+
+	GdkRectangle geometry;
+	guint      obscured : 1;
+	guint      dialog_up : 1;
+
+	guint      lock_enabled : 1;
+	guint      user_switch_enabled : 1;
+	guint      logout_enabled : 1;
+	guint      keyboard_enabled : 1;
+
+	guint64    logout_timeout;
+	char      *logout_command;
+	char      *keyboard_command;
+	char      *status_message;
+
+	GtkWidget *vbox;
+	GtkWidget *drawing_area;
+	GtkWidget *lock_box;
+	GtkWidget *lock_socket;
+	GtkWidget *keyboard_socket;
+	GtkWidget *info_bar;
+	GtkWidget *info_content;
+
+	cairo_surface_t *background_surface;
+
+	guint      popup_dialog_idle_id;
+
+	guint      dialog_map_signal_id;
+	guint      dialog_unmap_signal_id;
+	guint      dialog_response_signal_id;
+
+	guint      watchdog_timer_id;
+	guint      info_bar_timer_id;
+
+	gint       lock_pid;
+	gint       lock_watch_id;
+	gint       dialog_response;
+	gboolean   dialog_quit_requested;
+	gboolean   dialog_shake_in_progress;
+
+	gint       keyboard_pid;
+	gint       keyboard_watch_id;
+
+	GList     *key_events;
+
+	gdouble    last_x;
+	gdouble    last_y;
+
+	GTimer    *timer;
+
+#ifdef HAVE_SHAPE_EXT
+	int        shape_event_base;
+#endif
+};
+
+enum
+{
+    ACTIVITY,
+    DEACTIVATED,
+    LAST_SIGNAL
+};
+
+enum
+{
+    PROP_0,
+    PROP_OBSCURED,
+    PROP_DIALOG_UP,
+    PROP_LOCK_ENABLED,
+    PROP_LOGOUT_ENABLED,
+    PROP_KEYBOARD_ENABLED,
+    PROP_KEYBOARD_COMMAND,
+    PROP_LOGOUT_COMMAND,
+    PROP_LOGOUT_TIMEOUT,
+    PROP_MONITOR,
+    PROP_STATUS_MESSAGE
+};
+
+static guint           signals [LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSWindow, gs_window, GTK_TYPE_WINDOW)
+
+static void
+set_invisible_cursor (GdkWindow *window,
+                      gboolean   invisible)
+{
+	GdkDisplay *display;
+	GdkCursor *cursor = NULL;
+
+	if (invisible)
+	{
+		display = gdk_window_get_display (window);
+		cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR);
+	}
+
+	gdk_window_set_cursor (window, cursor);
+
+	if (cursor)
+	{
+		g_object_unref (cursor);
+	}
+}
+
+/* derived from tomboy */
+static void
+gs_window_override_user_time (GSWindow *window)
+{
+	guint32 ev_time = gtk_get_current_event_time ();
+
+	if (ev_time == 0)
+	{
+		gint ev_mask = gtk_widget_get_events (GTK_WIDGET (window));
+		if (!(ev_mask & GDK_PROPERTY_CHANGE_MASK))
+		{
+			gtk_widget_add_events (GTK_WIDGET (window),
+			                       GDK_PROPERTY_CHANGE_MASK);
+		}
+
+		/*
+		 * NOTE: Last resort for D-BUS or other non-interactive
+		 *       openings.  Causes roundtrip to server.  Lame.
+		 */
+		ev_time = gdk_x11_get_server_time (gtk_widget_get_window (GTK_WIDGET (window)));
+	}
+
+	gdk_x11_window_set_user_time (gtk_widget_get_window (GTK_WIDGET (window)), ev_time);
+}
+
+static void
+clear_children (Window window)
+{
+	Window            root;
+	Window            parent;
+	Window           *children;
+	unsigned int      n_children;
+	int               status;
+
+	children = NULL;
+	status = XQueryTree (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), window, &root, &parent, &children, &n_children);
+
+	if (status == 0)
+	{
+		if (children)
+		{
+			XFree (children);
+		}
+		return;
+	}
+
+	if (children)
+	{
+		while (n_children)
+		{
+			Window child;
+
+			child = children [--n_children];
+
+			XClearWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), child);
+
+			clear_children (child);
+		}
+
+		XFree (children);
+	}
+}
+
+static void
+widget_clear_all_children (GtkWidget *widget)
+{
+	GdkWindow *w;
+	GdkDisplay *display;
+
+	gs_debug ("Clearing all child windows");
+	display = gtk_widget_get_display (widget);
+
+	gdk_x11_display_error_trap_push (display);
+
+	w = gtk_widget_get_window (widget);
+
+	clear_children (GDK_WINDOW_XID (w));
+
+	gdk_x11_display_error_trap_pop_ignored (display);
+
+}
+
+void
+gs_window_set_background_surface (GSWindow        *window,
+                                  cairo_surface_t *surface)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	if (window->priv->background_surface != NULL)
+	{
+		cairo_surface_destroy (window->priv->background_surface);
+	}
+	window->priv->background_surface = NULL;
+
+	if (surface != NULL)
+	{
+		window->priv->background_surface = cairo_surface_reference (surface);
+	}
+
+	gtk_widget_queue_draw (GTK_WIDGET (window));
+}
+
+void
+gs_window_clear (GSWindow *window)
+{
+	GdkDisplay *display;
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	gs_debug ("Clearing widgets");
+
+	if (gtk_widget_get_realized (GTK_WIDGET (window)))
+	{
+		gtk_widget_queue_draw (GTK_WIDGET (window));
+		/* If a screensaver theme adds child windows
+		   we need to clear them too */
+		widget_clear_all_children (GTK_WIDGET (window));
+	}
+
+	if (gtk_widget_get_realized (window->priv->drawing_area))
+	{
+		gtk_widget_queue_draw (window->priv->drawing_area);
+		widget_clear_all_children (window->priv->drawing_area);
+	}
+
+	display = gtk_widget_get_display (GTK_WIDGET(window));
+	gdk_display_flush (display);
+}
+
+static cairo_region_t *
+get_outside_region (GSWindow *window)
+{
+	GdkDisplay *display;
+	int         i;
+	int         num_monitors;
+	cairo_region_t *region;
+
+	display = gtk_widget_get_display (GTK_WIDGET (window));
+
+	region = cairo_region_create ();
+
+	num_monitors = gdk_display_get_n_monitors (display);
+	for (i = 0; i < num_monitors; i++)
+	{
+		GdkMonitor *mon = gdk_display_get_monitor (display, i);
+
+		if (mon != window->priv->monitor)
+		{
+			GdkRectangle geometry;
+			cairo_rectangle_int_t rectangle;
+
+			gdk_monitor_get_geometry (mon, &geometry);
+			rectangle.x = geometry.x;
+			rectangle.y = geometry.y;
+			rectangle.width = geometry.width;
+			rectangle.height = geometry.height;
+			cairo_region_union_rectangle (region, &rectangle);
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	return region;
+}
+
+static void
+update_geometry (GSWindow *window)
+{
+	GdkRectangle geometry;
+	cairo_region_t *outside_region;
+	cairo_region_t *monitor_region;
+
+	outside_region = get_outside_region (window);
+
+	gdk_monitor_get_geometry (window->priv->monitor, &geometry);
+	gs_debug ("got geometry for monitor: x=%d y=%d w=%d h=%d",
+	          geometry.x,
+	          geometry.y,
+	          geometry.width,
+	          geometry.height);
+	monitor_region = cairo_region_create_rectangle ((const cairo_rectangle_int_t *)&geometry);
+	cairo_region_subtract (monitor_region, outside_region);
+	cairo_region_destroy (outside_region);
+
+	cairo_region_get_extents (monitor_region, (cairo_rectangle_int_t *)&geometry);
+	cairo_region_destroy (monitor_region);
+
+	gs_debug ("using geometry for monitor: x=%d y=%d w=%d h=%d",
+	          geometry.x,
+	          geometry.y,
+	          geometry.width,
+	          geometry.height);
+
+	window->priv->geometry.x = geometry.x;
+	window->priv->geometry.y = geometry.y;
+	window->priv->geometry.width = geometry.width;
+	window->priv->geometry.height = geometry.height;
+}
+
+static void
+monitor_geometry_notify (GdkMonitor *monitor,
+                         GParamSpec *pspec,
+                         GSWindow   *window)
+{
+	gs_debug ("Got monitor geometry notify signal");
+	gtk_widget_queue_resize (GTK_WIDGET (window));
+}
+
+/* copied from panel-toplevel.c */
+static void
+gs_window_move_resize_window (GSWindow *window,
+                              gboolean  move,
+                              gboolean  resize)
+{
+	GtkWidget *widget;
+	GdkWindow *gdkwindow;
+
+	widget = GTK_WIDGET (window);
+	gdkwindow = gtk_widget_get_window (widget);
+
+	g_assert (gtk_widget_get_realized (widget));
+
+	gs_debug ("Move and/or resize window: x=%d y=%d w=%d h=%d",
+	          window->priv->geometry.x,
+	          window->priv->geometry.y,
+	          window->priv->geometry.width,
+	          window->priv->geometry.height);
+
+	if (move && resize)
+	{
+		gdk_window_move_resize (gdkwindow,
+		                        window->priv->geometry.x,
+		                        window->priv->geometry.y,
+		                        window->priv->geometry.width,
+		                        window->priv->geometry.height);
+	}
+	else if (move)
+	{
+		gdk_window_move (gdkwindow,
+		                 window->priv->geometry.x,
+		                 window->priv->geometry.y);
+	}
+	else if (resize)
+	{
+		gdk_window_resize (gdkwindow,
+		                   window->priv->geometry.width,
+		                   window->priv->geometry.height);
+	}
+}
+
+static void
+gs_window_real_unrealize (GtkWidget *widget)
+{
+	GdkMonitor *monitor = GS_WINDOW (widget)->priv->monitor;
+
+	g_signal_handlers_disconnect_by_func (monitor, monitor_geometry_notify,
+	                                      widget);
+
+	if (GTK_WIDGET_CLASS (gs_window_parent_class)->unrealize)
+	{
+		GTK_WIDGET_CLASS (gs_window_parent_class)->unrealize (widget);
+	}
+}
+
+/* copied from gdk */
+extern char **environ;
+
+static gchar **
+spawn_make_environment_for_display (GdkDisplay *display,
+                                    gchar     **envp)
+{
+	gchar **retval = NULL;
+	const gchar *display_name;
+	gint    display_index = -1;
+	gint    i, env_len;
+
+	g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+	if (envp == NULL)
+		envp = environ;
+
+	for (env_len = 0; envp[env_len]; env_len++)
+		if (strncmp (envp[env_len], "DISPLAY", strlen ("DISPLAY")) == 0)
+			display_index = env_len;
+
+	retval = g_new (char *, env_len + 1);
+	retval[env_len] = NULL;
+
+	display_name = gdk_display_get_name (display);
+
+	for (i = 0; i < env_len; i++)
+		if (i == display_index)
+			retval[i] = g_strconcat ("DISPLAY=", display_name, NULL);
+		else
+			retval[i] = g_strdup (envp[i]);
+
+	g_assert (i == env_len);
+
+	return retval;
+}
+
+static gboolean
+spawn_command_line_on_display_sync (GdkDisplay  *display,
+                                    const gchar  *command_line,
+                                    char        **standard_output,
+                                    char        **standard_error,
+                                    int          *exit_status,
+                                    GError      **error)
+{
+	char     **argv = NULL;
+	char     **envp = NULL;
+	gboolean   retval;
+
+	g_return_val_if_fail (command_line != NULL, FALSE);
+
+	if (! g_shell_parse_argv (command_line, NULL, &argv, error))
+	{
+		return FALSE;
+	}
+
+	envp = spawn_make_environment_for_display (display, NULL);
+
+	retval = g_spawn_sync (NULL,
+	                       argv,
+	                       envp,
+	                       G_SPAWN_SEARCH_PATH,
+	                       NULL,
+	                       NULL,
+	                       standard_output,
+	                       standard_error,
+	                       exit_status,
+	                       error);
+
+	g_strfreev (argv);
+	g_strfreev (envp);
+
+	return retval;
+}
+
+static GdkVisual *
+get_best_visual_for_display (GdkDisplay *display)
+{
+	GdkScreen    *screen;
+	char         *std_output;
+	int           exit_status;
+	GError       *error;
+	unsigned long v;
+	char          c;
+	GdkVisual    *visual;
+	gboolean      res;
+
+	visual = NULL;
+	screen = gdk_display_get_default_screen (display);
+
+	error = NULL;
+	std_output = NULL;
+	res = spawn_command_line_on_display_sync (display,
+	        MATE_SCREENSAVER_GL_HELPER_PATH,
+	        &std_output,
+	        NULL,
+	        &exit_status,
+	        &error);
+	if (! res)
+	{
+		gs_debug ("Could not run command '%s': %s",
+		          MATE_SCREENSAVER_GL_HELPER_PATH, error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	if (1 == sscanf (std_output, "0x%lx %c", &v, &c))
+	{
+		if (v != 0)
+		{
+			VisualID      visual_id;
+
+			visual_id = (VisualID) v;
+			visual = gdk_x11_screen_lookup_visual (screen, visual_id);
+
+			gs_debug ("Found best GL visual for display %s: 0x%x",
+			          gdk_display_get_name (display),
+			          (unsigned int) visual_id);
+		}
+	}
+out:
+	g_free (std_output);
+
+	return g_object_ref (visual);
+}
+
+static void
+widget_set_best_visual (GtkWidget *widget)
+{
+	GdkVisual *visual;
+
+	g_return_if_fail (widget != NULL);
+
+	visual = get_best_visual_for_display (gtk_widget_get_display (widget));
+	if (visual != NULL)
+	{
+		gtk_widget_set_visual (widget, visual);
+		g_object_unref (visual);
+	}
+}
+
+static void
+gs_window_real_realize (GtkWidget *widget)
+{
+	GdkMonitor *monitor = GS_WINDOW (widget)->priv->monitor;
+
+	widget_set_best_visual (widget);
+
+	if (GTK_WIDGET_CLASS (gs_window_parent_class)->realize)
+	{
+		GTK_WIDGET_CLASS (gs_window_parent_class)->realize (widget);
+	}
+
+	gs_window_override_user_time (GS_WINDOW (widget));
+
+	gs_window_move_resize_window (GS_WINDOW (widget), TRUE, TRUE);
+
+	g_signal_connect (monitor,
+	                  "notify::geometry",
+	                  G_CALLBACK (monitor_geometry_notify),
+	                  widget);
+}
+
+/* every so often we should raise the window in case
+   another window has somehow gotten on top */
+static gboolean
+watchdog_timer (GSWindow *window)
+{
+	GtkWidget *widget = GTK_WIDGET (window);
+
+	gdk_window_focus (gtk_widget_get_window (widget), GDK_CURRENT_TIME);
+
+	return TRUE;
+}
+
+static void
+remove_watchdog_timer (GSWindow *window)
+{
+	if (window->priv->watchdog_timer_id != 0)
+	{
+		g_source_remove (window->priv->watchdog_timer_id);
+		window->priv->watchdog_timer_id = 0;
+	}
+}
+
+static void
+add_watchdog_timer (GSWindow *window,
+                    guint     timeout)
+{
+	window->priv->watchdog_timer_id = g_timeout_add (timeout,
+	                                                 (GSourceFunc)watchdog_timer,
+	                                                 window);
+}
+
+static void
+remove_popup_dialog_idle (GSWindow *window)
+{
+	if (window->priv->popup_dialog_idle_id != 0)
+	{
+		g_source_remove (window->priv->popup_dialog_idle_id);
+		window->priv->popup_dialog_idle_id = 0;
+	}
+}
+
+static void
+add_popup_dialog_idle (GSWindow *window)
+{
+	window->priv->popup_dialog_idle_id = g_idle_add (popup_dialog_idle, window);
+}
+
+static gboolean
+emit_deactivated_idle (GSWindow *window)
+{
+	g_signal_emit (window, signals [DEACTIVATED], 0);
+
+	return FALSE;
+}
+
+static void
+add_emit_deactivated_idle (GSWindow *window)
+{
+	g_idle_add ((GSourceFunc)emit_deactivated_idle, window);
+}
+
+static void
+gs_window_raise (GSWindow *window)
+{
+	GdkWindow *win;
+
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	gs_debug ("Raising screensaver window");
+
+	win = gtk_widget_get_window (GTK_WIDGET (window));
+
+	gdk_window_raise (win);
+}
+
+static gboolean
+x11_window_is_ours (Window window)
+{
+	GdkWindow *gwindow;
+	gboolean   ret;
+
+	ret = FALSE;
+
+	gwindow = gdk_x11_window_lookup_for_display (gdk_display_get_default (), window);
+	if (gwindow && (window != GDK_ROOT_WINDOW ()))
+	{
+		ret = TRUE;
+	}
+
+	return ret;
+}
+
+#ifdef HAVE_SHAPE_EXT
+static void
+unshape_window (GSWindow *window)
+{
+	gdk_window_shape_combine_region (gtk_widget_get_window (GTK_WIDGET (window)),
+	                                 NULL,
+	                                 0,
+	                                 0);
+}
+#endif
+
+static void
+gs_window_xevent (GSWindow  *window,
+                  GdkXEvent *xevent)
+{
+	XEvent *ev;
+
+	ev = xevent;
+
+	/* MapNotify is used to tell us when new windows are mapped.
+	   ConfigureNofify is used to tell us when windows are raised. */
+	switch (ev->xany.type)
+	{
+	case MapNotify:
+	{
+		XMapEvent *xme = &ev->xmap;
+
+		if (! x11_window_is_ours (xme->window))
+		{
+			gs_window_raise (window);
+		}
+		else
+		{
+			gs_debug ("not raising our windows");
+		}
+
+		break;
+	}
+	case ConfigureNotify:
+	{
+		XConfigureEvent *xce = &ev->xconfigure;
+
+		if (! x11_window_is_ours (xce->window))
+		{
+			gs_window_raise (window);
+		}
+		else
+		{
+			gs_debug ("not raising our windows");
+		}
+
+		break;
+	}
+	default:
+		/* extension events */
+#ifdef HAVE_SHAPE_EXT
+		if (ev->xany.type == (window->priv->shape_event_base + ShapeNotify))
+		{
+			/*XShapeEvent *xse = (XShapeEvent *) ev;*/
+			unshape_window (window);
+			gs_debug ("Window was reshaped!");
+		}
+#endif
+
+		break;
+	}
+
+}
+
+static GdkFilterReturn
+xevent_filter (GdkXEvent *xevent,
+               GdkEvent  *event,
+               GSWindow  *window)
+{
+	gs_window_xevent (window, xevent);
+
+	return GDK_FILTER_CONTINUE;
+}
+
+static void
+select_popup_events (void)
+{
+	XWindowAttributes attr;
+	unsigned long     events;
+	GdkDisplay *display;
+
+	display = gdk_display_get_default ();
+
+	gdk_x11_display_error_trap_push (display);
+
+	memset (&attr, 0, sizeof (attr));
+	XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (display), GDK_ROOT_WINDOW (), &attr);
+
+	events = SubstructureNotifyMask | attr.your_event_mask;
+	XSelectInput (GDK_DISPLAY_XDISPLAY (display), GDK_ROOT_WINDOW (), events);
+
+	gdk_x11_display_error_trap_pop_ignored (display);
+}
+
+static void
+window_select_shape_events (GSWindow *window)
+{
+#ifdef HAVE_SHAPE_EXT
+	unsigned long events;
+	int           shape_error_base;
+	GdkDisplay *display;
+
+	display = gtk_widget_get_display (GTK_WIDGET(window));
+
+	gdk_x11_display_error_trap_push (display);
+
+	if (XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display), &window->priv->shape_event_base, &shape_error_base)) {
+		events = ShapeNotifyMask;
+		XShapeSelectInput (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (window))), events);
+	}
+
+	gdk_x11_display_error_trap_pop_ignored (display);
+#endif
+}
+
+static gboolean
+gs_window_real_draw (GtkWidget *widget,
+                     cairo_t   *cr)
+{
+	GSWindow *window = GS_WINDOW (widget);
+	cairo_surface_t *bg_surface = window->priv->background_surface;
+
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+	if (bg_surface != NULL)
+	{
+		cairo_set_source_surface (cr, bg_surface, 0, 0);
+	}
+	else
+	{
+		cairo_set_source_rgb (cr, 0, 0, 0);
+	}
+	cairo_paint (cr);
+
+	return FALSE;
+}
+
+static void
+gs_window_real_show (GtkWidget *widget)
+{
+	GSWindow *window;
+
+	if (GTK_WIDGET_CLASS (gs_window_parent_class)->show)
+	{
+		GTK_WIDGET_CLASS (gs_window_parent_class)->show (widget);
+	}
+
+	gs_window_clear (GS_WINDOW (widget));
+
+	set_invisible_cursor (gtk_widget_get_window (widget), TRUE);
+
+	window = GS_WINDOW (widget);
+	if (window->priv->timer)
+	{
+		g_timer_destroy (window->priv->timer);
+	}
+	window->priv->timer = g_timer_new ();
+
+	remove_watchdog_timer (window);
+	add_watchdog_timer (window, 30000);
+
+	select_popup_events ();
+	window_select_shape_events (window);
+	gdk_window_add_filter (NULL, (GdkFilterFunc)xevent_filter, window);
+}
+
+static void
+set_info_text_and_icon (GSWindow   *window,
+                        const char *icon_name,
+                        const char *primary_text,
+                        const char *secondary_text)
+{
+	GtkWidget *content_area;
+	GtkWidget *hbox_content;
+	GtkWidget *image;
+	GtkWidget *vbox;
+	gchar *primary_markup;
+	gchar *secondary_markup;
+	GtkWidget *primary_label;
+	GtkWidget *secondary_label;
+
+	hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
+	gtk_widget_show (hbox_content);
+
+	image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DIALOG);
+	gtk_widget_show (image);
+	gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0);
+	gtk_widget_set_valign (image, GTK_ALIGN_START);
+
+	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+	gtk_widget_show (vbox);
+	gtk_box_pack_start (GTK_BOX (hbox_content), vbox, FALSE, FALSE, 0);
+
+	primary_markup = g_strdup_printf ("<b>%s</b>", primary_text);
+	primary_label = gtk_label_new (primary_markup);
+	g_free (primary_markup);
+	gtk_widget_show (primary_label);
+	gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
+	gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+	gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+	gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
+
+	if (secondary_text != NULL)
+	{
+		secondary_markup = g_strdup_printf ("<small>%s</small>",
+		                                    secondary_text);
+		secondary_label = gtk_label_new (secondary_markup);
+		g_free (secondary_markup);
+		gtk_widget_show (secondary_label);
+		gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
+		gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
+		gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+		gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
+	}
+
+	/* remove old content */
+	content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (window->priv->info_bar));
+	if (window->priv->info_content != NULL)
+	{
+		gtk_container_remove (GTK_CONTAINER (content_area), window->priv->info_content);
+	}
+	gtk_box_pack_start (GTK_BOX (content_area),
+	                    hbox_content,
+	                    TRUE, FALSE, 0);
+	window->priv->info_content = hbox_content;
+}
+
+static gboolean
+info_bar_timeout (GSWindow *window)
+{
+	window->priv->info_bar_timer_id = 0;
+	gtk_widget_hide (window->priv->info_bar);
+	return FALSE;
+}
+
+void
+gs_window_show_message (GSWindow   *window,
+                        const char *summary,
+                        const char *body,
+                        const char *icon)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	set_info_text_and_icon (window,
+	                        icon,
+	                        summary,
+	                        body);
+	gtk_widget_show (window->priv->info_bar);
+
+	if (window->priv->info_bar_timer_id > 0)
+	{
+		g_source_remove (window->priv->info_bar_timer_id);
+	}
+
+	window->priv->info_bar_timer_id = g_timeout_add_seconds (INFO_BAR_SECONDS,
+	                                  (GSourceFunc)info_bar_timeout,
+	                                  window);
+}
+
+void
+gs_window_show (GSWindow *window)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	gtk_widget_show (GTK_WIDGET (window));
+}
+
+static void
+gs_window_real_hide (GtkWidget *widget)
+{
+	GSWindow *window;
+
+	window = GS_WINDOW (widget);
+
+	gdk_window_remove_filter (NULL, (GdkFilterFunc)xevent_filter, window);
+
+	remove_watchdog_timer (window);
+
+	if (GTK_WIDGET_CLASS (gs_window_parent_class)->hide)
+	{
+		GTK_WIDGET_CLASS (gs_window_parent_class)->hide (widget);
+	}
+}
+
+void
+gs_window_destroy (GSWindow *window)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	gs_window_cancel_unlock_request (window);
+
+	gtk_widget_destroy (GTK_WIDGET (window));
+}
+
+GdkWindow *
+gs_window_get_gdk_window (GSWindow *window)
+{
+	g_return_val_if_fail (GS_IS_WINDOW (window), NULL);
+
+	return gtk_widget_get_window (GTK_WIDGET (window));
+}
+
+GtkWidget *
+gs_window_get_drawing_area (GSWindow *window)
+{
+	g_return_val_if_fail (GS_IS_WINDOW (window), NULL);
+
+	return window->priv->drawing_area;
+}
+
+/* just for debugging */
+static gboolean
+error_watch (GIOChannel   *source,
+             GIOCondition  condition,
+             gpointer      data)
+{
+	gboolean finished = FALSE;
+
+	if (condition & G_IO_IN)
+	{
+		GIOStatus status;
+		GError   *error = NULL;
+		char     *line;
+
+		line = NULL;
+		status = g_io_channel_read_line (source, &line, NULL, NULL, &error);
+
+		switch (status)
+		{
+		case G_IO_STATUS_NORMAL:
+			gs_debug ("command error output: %s", line);
+			break;
+		case G_IO_STATUS_EOF:
+			finished = TRUE;
+			break;
+		case G_IO_STATUS_ERROR:
+			finished = TRUE;<--- Variable 'finished' is assigned a value that is never used.
+			gs_debug ("Error reading from child: %s\n", error->message);
+			g_error_free (error);
+			return FALSE;
+		case G_IO_STATUS_AGAIN:
+		default:
+			break;
+		}
+		g_free (line);
+	}
+	else if (condition & G_IO_HUP)
+	{
+		finished = TRUE;
+	}
+
+	if (finished)
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+spawn_on_window (GSWindow *window,
+                 char     *command,
+                 int      *pid,
+                 GIOFunc   watch_func,
+                 gpointer  user_data,
+                 gint     *watch_id)
+{
+	int         argc;
+	char      **argv;
+	char      **envp;
+	GError     *error;
+	gboolean    result;
+	GIOChannel *channel;
+	int         standard_output;
+	int         standard_error;
+	int         child_pid;
+	int         id;
+
+	error = NULL;
+	if (! g_shell_parse_argv (command, &argc, &argv, &error))
+	{
+		gs_debug ("Could not parse command: %s", error->message);
+		g_error_free (error);
+		return FALSE;
+	}
+
+	error = NULL;
+	envp = spawn_make_environment_for_display (gtk_widget_get_display (GTK_WIDGET (window)), NULL);
+	result = g_spawn_async_with_pipes (NULL,
+	                                   argv,
+	                                   envp,
+	                                   G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
+	                                   NULL,
+	                                   NULL,
+	                                   &child_pid,
+	                                   NULL,
+	                                   &standard_output,
+	                                   &standard_error,
+	                                   &error);
+
+	if (! result)
+	{
+		gs_debug ("Could not start command '%s': %s", command, error->message);
+		g_error_free (error);
+		g_strfreev (argv);
+		return FALSE;
+	}
+
+	if (pid != NULL)
+	{
+		*pid = child_pid;
+	}
+	else
+	{
+		g_spawn_close_pid (child_pid);
+	}
+
+	/* output channel */
+	channel = g_io_channel_unix_new (standard_output);
+	g_io_channel_set_close_on_unref (channel, TRUE);
+	g_io_channel_set_flags (channel,
+	                        g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK,
+	                        NULL);
+	id = g_io_add_watch (channel,
+	                     G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+	                     watch_func,
+	                     user_data);
+	if (watch_id != NULL)
+	{
+		*watch_id = id;
+	}
+	g_io_channel_unref (channel);
+
+	/* error channel */
+	channel = g_io_channel_unix_new (standard_error);
+	g_io_channel_set_close_on_unref (channel, TRUE);
+	g_io_channel_set_flags (channel,
+	                        g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK,
+	                        NULL);
+	id = g_io_add_watch (channel,<--- Variable 'id' is assigned a value that is never used.
+	                     G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+	                     error_watch,
+	                     NULL);
+	g_io_channel_unref (channel);
+
+	g_strfreev (argv);
+	g_strfreev (envp);
+
+	return result;
+}
+
+static void
+lock_plug_added (GtkWidget *widget,
+                 GSWindow  *window)
+{
+	gtk_widget_show (widget);
+}
+
+static gboolean
+lock_plug_removed (GtkWidget *widget,
+                   GSWindow  *window)
+{
+	gtk_widget_hide (widget);
+	gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->lock_box));
+	window->priv->lock_box = NULL;
+
+	return TRUE;
+}
+
+static void
+keyboard_plug_added (GtkWidget *widget,
+                     GSWindow  *window)
+{
+	gtk_widget_show (widget);
+}
+
+static gboolean
+keyboard_plug_removed (GtkWidget *widget,
+                       GSWindow  *window)
+{
+	gtk_widget_hide (widget);
+	gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->keyboard_socket));
+
+	return TRUE;
+}
+
+static void
+keyboard_socket_destroyed (GtkWidget *widget,
+                           GSWindow  *window)
+{
+	g_signal_handlers_disconnect_by_func (widget, keyboard_socket_destroyed, window);
+	g_signal_handlers_disconnect_by_func (widget, keyboard_plug_added, window);
+	g_signal_handlers_disconnect_by_func (widget, keyboard_plug_removed, window);
+
+	window->priv->keyboard_socket = NULL;
+}
+
+static void
+forward_key_events (GSWindow *window)
+{
+	window->priv->key_events = g_list_reverse (window->priv->key_events);
+
+	while (window->priv->key_events != NULL)
+	{
+		GdkEventKey *event = window->priv->key_events->data;
+
+		gtk_window_propagate_key_event (GTK_WINDOW (window), event);
+
+		gdk_event_free ((GdkEvent *)event);
+		window->priv->key_events = g_list_delete_link (window->priv->key_events,
+		                           window->priv->key_events);
+	}
+}
+
+static void
+remove_key_events (GSWindow *window)
+{
+	window->priv->key_events = g_list_reverse (window->priv->key_events);
+
+	while (window->priv->key_events)
+	{
+		GdkEventKey *event = window->priv->key_events->data;
+
+		gdk_event_free ((GdkEvent *)event);
+		window->priv->key_events = g_list_delete_link (window->priv->key_events,
+		                           window->priv->key_events);
+	}
+}
+
+static void
+lock_socket_show (GtkWidget *widget,
+                  GSWindow  *window)
+{
+	gtk_widget_child_focus (window->priv->lock_socket, GTK_DIR_TAB_FORWARD);
+
+	/* send queued events to the dialog */
+	forward_key_events (window);
+}
+
+static void
+lock_socket_destroyed (GtkWidget *widget,
+                       GSWindow  *window)
+{
+	g_signal_handlers_disconnect_by_func (widget, lock_socket_show, window);
+	g_signal_handlers_disconnect_by_func (widget, lock_socket_destroyed, window);
+	g_signal_handlers_disconnect_by_func (widget, lock_plug_added, window);
+	g_signal_handlers_disconnect_by_func (widget, lock_plug_removed, window);
+
+	window->priv->lock_socket = NULL;
+}
+
+static void
+create_keyboard_socket (GSWindow *window,
+                        guint32   id)
+{
+	int height;
+
+	height = (HeightOfScreen (gdk_x11_screen_get_xscreen (gtk_widget_get_screen (GTK_WIDGET (window))))) / 4;
+
+	window->priv->keyboard_socket = gtk_socket_new ();
+	gtk_widget_set_size_request (window->priv->keyboard_socket, -1, height);
+
+	g_signal_connect (window->priv->keyboard_socket, "destroy",
+	                  G_CALLBACK (keyboard_socket_destroyed), window);
+	g_signal_connect (window->priv->keyboard_socket, "plug_added",
+	                  G_CALLBACK (keyboard_plug_added), window);
+	g_signal_connect (window->priv->keyboard_socket, "plug_removed",
+	                  G_CALLBACK (keyboard_plug_removed), window);
+	gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->keyboard_socket, FALSE, FALSE, 0);
+	gtk_socket_add_id (GTK_SOCKET (window->priv->keyboard_socket), id);
+}
+
+/* adapted from gspawn.c */
+static int
+wait_on_child (int pid)
+{
+	int status;
+
+wait_again:
+	if (waitpid (pid, &status, 0) < 0)
+	{
+		if (errno == EINTR)
+		{
+			goto wait_again;
+		}
+		else if (errno == ECHILD)
+		{
+			; /* do nothing, child already reaped */
+		}
+		else
+		{
+			gs_debug ("waitpid () should not fail in 'GSWindow'");
+		}
+	}
+
+	return status;
+}
+
+static void
+kill_keyboard_command (GSWindow *window)
+{
+	if (window->priv->keyboard_pid > 0)
+	{
+		signal_pid (window->priv->keyboard_pid, SIGTERM);
+	}
+}
+
+static void
+kill_dialog_command (GSWindow *window)
+{
+	/* If a dialog is up we need to signal it
+	   and wait on it */
+	if (window->priv->lock_pid > 0)
+	{
+		signal_pid (window->priv->lock_pid, SIGTERM);
+	}
+}
+
+static void
+keyboard_command_finish (GSWindow *window)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	/* send a signal just in case */
+	kill_keyboard_command (window);
+
+	gs_debug ("Keyboard finished");
+
+	if (window->priv->keyboard_pid > 0)
+	{
+		wait_on_child (window->priv->keyboard_pid);
+
+		g_spawn_close_pid (window->priv->keyboard_pid);
+		window->priv->keyboard_pid = 0;
+	}
+}
+
+static gboolean
+keyboard_command_watch (GIOChannel   *source,
+                        GIOCondition  condition,
+                        GSWindow     *window)
+{
+	gboolean finished = FALSE;
+
+	g_return_val_if_fail (GS_IS_WINDOW (window), FALSE);
+
+	if (condition & G_IO_IN)
+	{
+		GIOStatus status;
+		GError   *error = NULL;
+		char     *line;
+
+		line = NULL;
+		status = g_io_channel_read_line (source, &line, NULL, NULL, &error);
+
+		switch (status)
+		{
+		case G_IO_STATUS_NORMAL:
+		{
+			guint32 id;
+			char    c;
+			gs_debug ("keyboard command output: %s", line);
+			if (1 == sscanf (line, " %" G_GUINT32_FORMAT " %c", &id, &c))
+			{
+				create_keyboard_socket (window, id);
+			}
+		}
+		break;
+		case G_IO_STATUS_EOF:
+			finished = TRUE;
+			break;
+		case G_IO_STATUS_ERROR:
+			finished = TRUE;<--- Variable 'finished' is assigned a value that is never used.
+			gs_debug ("Error reading from child: %s\n", error->message);
+			g_error_free (error);
+			return FALSE;
+		case G_IO_STATUS_AGAIN:
+		default:
+			break;
+		}
+
+		g_free (line);
+	}
+	else if (condition & G_IO_HUP)
+	{
+		finished = TRUE;
+	}
+
+	if (finished)
+	{
+		window->priv->keyboard_watch_id = 0;
+		keyboard_command_finish (window);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+embed_keyboard (GSWindow *window)
+{
+	gboolean res;
+
+	if (! window->priv->keyboard_enabled
+	        || window->priv->keyboard_command == NULL)
+		return;
+
+	gs_debug ("Adding embedded keyboard widget");
+
+	/* FIXME: verify command is safe */
+
+	gs_debug ("Running command: %s", window->priv->keyboard_command);
+
+	res = spawn_on_window (window,
+	                       window->priv->keyboard_command,
+	                       &window->priv->keyboard_pid,
+	                       (GIOFunc)keyboard_command_watch,
+	                       window,
+	                       &window->priv->keyboard_watch_id);
+	if (! res)
+	{
+		gs_debug ("Could not start command: %s", window->priv->keyboard_command);
+	}
+}
+
+static void
+create_lock_socket (GSWindow *window,
+                    guint32   id)
+{
+	window->priv->lock_socket = gtk_socket_new ();
+	window->priv->lock_box = gtk_grid_new ();
+	gtk_widget_set_halign (GTK_WIDGET (window->priv->lock_box),
+	                       GTK_ALIGN_CENTER);
+	gtk_widget_set_valign (GTK_WIDGET (window->priv->lock_box),
+	                       GTK_ALIGN_CENTER);
+	gtk_widget_show (window->priv->lock_box);
+	gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->lock_box, TRUE, TRUE, 0);
+
+	gtk_container_add (GTK_CONTAINER (window->priv->lock_box), window->priv->lock_socket);
+
+	g_signal_connect (window->priv->lock_socket, "show",
+	                  G_CALLBACK (lock_socket_show), window);
+	g_signal_connect (window->priv->lock_socket, "destroy",
+	                  G_CALLBACK (lock_socket_destroyed), window);
+	g_signal_connect (window->priv->lock_socket, "plug_added",
+	                  G_CALLBACK (lock_plug_added), window);
+	g_signal_connect (window->priv->lock_socket, "plug_removed",
+	                  G_CALLBACK (lock_plug_removed), window);
+
+	gtk_socket_add_id (GTK_SOCKET (window->priv->lock_socket), id);
+
+	if (window->priv->keyboard_enabled)
+	{
+		embed_keyboard (window);
+	}
+}
+
+static void
+gs_window_dialog_finish (GSWindow *window)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	gs_debug ("Dialog finished");
+
+	/* make sure we finish the keyboard thing too */
+	keyboard_command_finish (window);
+
+	/* send a signal just in case */
+	kill_dialog_command (window);
+
+	if (window->priv->lock_pid > 0)
+	{
+		wait_on_child (window->priv->lock_pid);
+
+		g_spawn_close_pid (window->priv->lock_pid);
+		window->priv->lock_pid = 0;
+	}
+
+	/* remove events for the case were we failed to show socket */
+	remove_key_events (window);
+}
+
+static void
+maybe_kill_dialog (GSWindow *window)
+{
+	if (!window->priv->dialog_shake_in_progress
+	        && window->priv->dialog_quit_requested
+	        && window->priv->lock_pid > 0)
+	{
+		kill (window->priv->lock_pid, SIGTERM);
+	}
+}
+
+/* very rudimentary animation for indicating an auth failure */
+static void
+shake_dialog (GSWindow *window)
+{
+	int   i;
+	guint start, end;
+
+	window->priv->dialog_shake_in_progress = TRUE;
+
+	for (i = 0; i < 8; i++)
+	{
+		if (i % 2 == 0)
+		{
+			start = 30;
+			end = 0;
+		}
+		else
+		{
+			start = 0;
+			end = 30;
+		}
+
+		if (! window->priv->lock_box)
+		{
+			break;
+		}
+
+		gtk_widget_set_margin_start (GTK_WIDGET (window->priv->lock_box),
+		                             start);
+		gtk_widget_set_margin_end (GTK_WIDGET (window->priv->lock_box),
+		                           end);
+
+		while (gtk_events_pending ())
+		{
+			gtk_main_iteration ();
+		}
+
+		g_usleep (10000);
+	}
+
+	window->priv->dialog_shake_in_progress = FALSE;
+	maybe_kill_dialog (window);
+}
+
+static void
+window_set_dialog_up (GSWindow *window,
+                      gboolean  dialog_up)
+{
+	if (window->priv->dialog_up == dialog_up)
+	{
+		return;
+	}
+
+	window->priv->dialog_up = (dialog_up != FALSE);
+	g_object_notify (G_OBJECT (window), "dialog-up");
+}
+
+static void
+popdown_dialog (GSWindow *window)
+{
+	gs_window_dialog_finish (window);
+
+	gtk_widget_show (window->priv->drawing_area);
+
+	gs_window_clear (window);
+	set_invisible_cursor (gtk_widget_get_window (GTK_WIDGET (window)), TRUE);
+
+	window_set_dialog_up (window, FALSE);
+
+	/* reset the pointer positions */
+	window->priv->last_x = -1;
+	window->priv->last_y = -1;
+
+	if (window->priv->lock_box != NULL)
+	{
+		gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->lock_box));
+		window->priv->lock_box = NULL;
+	}
+
+	remove_popup_dialog_idle (window);
+	remove_command_watches (window);
+}
+
+static gboolean
+lock_command_watch (GIOChannel   *source,
+                    GIOCondition  condition,
+                    GSWindow     *window)
+{
+	gboolean finished = FALSE;
+
+	g_return_val_if_fail (GS_IS_WINDOW (window), FALSE);
+
+	if (condition & G_IO_IN)
+	{
+		GIOStatus status;
+		GError   *error = NULL;
+		char     *line;
+
+		line = NULL;
+		status = g_io_channel_read_line (source, &line, NULL, NULL, &error);
+
+		switch (status)
+		{
+		case G_IO_STATUS_NORMAL:
+			gs_debug ("command output: %s", line);
+
+			if (strstr (line, "WINDOW ID=") != NULL)
+			{
+				guint32 id;
+				char    c;
+				if (1 == sscanf (line, " WINDOW ID= %" G_GUINT32_FORMAT " %c", &id, &c))
+				{
+					create_lock_socket (window, id);
+				}
+			}
+			else if (strstr (line, "NOTICE=") != NULL)
+			{
+				if (strstr (line, "NOTICE=AUTH FAILED") != NULL)
+				{
+					shake_dialog (window);
+				}
+			}
+			else if (strstr (line, "RESPONSE=") != NULL)
+			{
+				if (strstr (line, "RESPONSE=OK") != NULL)
+				{
+					gs_debug ("Got OK response");
+					window->priv->dialog_response = DIALOG_RESPONSE_OK;
+				}
+				else
+				{
+					gs_debug ("Got CANCEL response");
+					window->priv->dialog_response = DIALOG_RESPONSE_CANCEL;
+				}
+				finished = TRUE;
+			}
+			else if (strstr (line, "REQUEST QUIT") != NULL)
+			{
+				gs_debug ("Got request for quit");
+				window->priv->dialog_quit_requested = TRUE;
+				maybe_kill_dialog (window);
+			}
+			break;
+		case G_IO_STATUS_EOF:
+			finished = TRUE;
+			break;
+		case G_IO_STATUS_ERROR:
+			finished = TRUE;<--- Variable 'finished' is assigned a value that is never used.
+			gs_debug ("Error reading from child: %s\n", error->message);
+			g_error_free (error);
+			return FALSE;
+		case G_IO_STATUS_AGAIN:
+		default:
+			break;
+		}
+
+		g_free (line);
+	}
+	else if (condition & G_IO_HUP)
+	{
+		finished = TRUE;
+	}
+
+	if (finished)
+	{
+		popdown_dialog (window);
+
+		if (window->priv->dialog_response == DIALOG_RESPONSE_OK)
+		{
+			add_emit_deactivated_idle (window);
+		}
+
+		window->priv->lock_watch_id = 0;
+
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+is_logout_enabled (GSWindow *window)
+{
+	double elapsed;
+
+	if (! window->priv->logout_enabled)
+	{
+		return FALSE;
+	}
+
+	if (! window->priv->logout_command)
+	{
+		return FALSE;
+	}
+
+	elapsed = g_timer_elapsed (window->priv->timer, NULL);
+
+	if (window->priv->logout_timeout < (elapsed * 1000))
+	{
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+is_user_switch_enabled (GSWindow *window)
+{
+	return window->priv->user_switch_enabled;
+}
+
+static void
+popup_dialog (GSWindow *window)
+{
+	gboolean  result;
+	GString  *command;
+
+	gs_debug ("Popping up dialog");
+
+	command = g_string_new (MATE_SCREENSAVER_DIALOG_PATH);
+
+	if (is_logout_enabled (window))
+	{
+		command = g_string_append (command, " --enable-logout");
+		g_string_append_printf (command, " --logout-command='%s'", window->priv->logout_command);
+	}
+
+	if (window->priv->status_message)
+	{
+		char *quoted;
+
+		quoted = g_shell_quote (window->priv->status_message);
+		g_string_append_printf (command, " --status-message=%s", quoted);
+		g_free (quoted);
+	}
+
+	if (is_user_switch_enabled (window))
+	{
+		command = g_string_append (command, " --enable-switch");
+	}
+
+	if (gs_debug_enabled ())
+	{
+		command = g_string_append (command, " --verbose");
+	}
+
+	gtk_widget_hide (window->priv->drawing_area);
+
+	gtk_widget_queue_draw (GTK_WIDGET (window));
+	set_invisible_cursor (gtk_widget_get_window (GTK_WIDGET (window)), FALSE);
+
+	window->priv->dialog_quit_requested = FALSE;
+	window->priv->dialog_shake_in_progress = FALSE;
+
+	result = spawn_on_window (window,
+	                          command->str,
+	                          &window->priv->lock_pid,
+	                          (GIOFunc)lock_command_watch,
+	                          window,
+	                          &window->priv->lock_watch_id);
+	if (! result)
+	{
+		gs_debug ("Could not start command: %s", command->str);
+	}
+
+	g_string_free (command, TRUE);
+}
+
+static gboolean
+popup_dialog_idle (gpointer data)
+{
+	GSWindow *window = data;
+
+	popup_dialog (window);
+	window->priv->popup_dialog_idle_id = 0;
+	return FALSE;
+}
+
+void
+gs_window_request_unlock (GSWindow *window)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	gs_debug ("Requesting unlock");
+
+	if (! gtk_widget_get_visible (GTK_WIDGET (window)))
+	{
+		gs_debug ("Request unlock but window is not visible!");
+		return;
+	}
+
+	if (window->priv->lock_watch_id > 0)
+	{
+		return;
+	}
+
+	if (! window->priv->lock_enabled)
+	{
+		add_emit_deactivated_idle (window);
+
+		return;
+	}
+
+	if (window->priv->popup_dialog_idle_id == 0)
+	{
+		add_popup_dialog_idle (window);
+	}
+
+	window_set_dialog_up (window, TRUE);
+}
+
+void
+gs_window_cancel_unlock_request (GSWindow  *window)
+{
+	/* FIXME: This is a bit of a hammer approach...
+	* Maybe we should send a delete-event to
+	 * the plug?
+	 */
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	popdown_dialog (window);
+}
+
+void
+gs_window_set_lock_enabled (GSWindow *window,
+                            gboolean  lock_enabled)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	if (window->priv->lock_enabled == lock_enabled)
+	{
+		return;
+	}
+
+	window->priv->lock_enabled = (lock_enabled != FALSE);
+	g_object_notify (G_OBJECT (window), "lock-enabled");
+}
+
+GdkDisplay *
+gs_window_get_display (GSWindow  *window)
+{
+	g_return_val_if_fail (GS_IS_WINDOW (window), NULL);
+
+	return gtk_widget_get_display (GTK_WIDGET (window));
+}
+
+void
+gs_window_set_keyboard_enabled (GSWindow *window,
+                                gboolean  enabled)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	window->priv->keyboard_enabled = (enabled != FALSE);
+}
+
+void
+gs_window_set_keyboard_command (GSWindow   *window,
+                                const char *command)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	g_free (window->priv->keyboard_command);
+
+	if (command != NULL)
+	{
+		window->priv->keyboard_command = g_strdup (command);
+	}
+	else
+	{
+		window->priv->keyboard_command = NULL;
+	}
+}
+
+void
+gs_window_set_logout_enabled (GSWindow *window,
+                              gboolean  logout_enabled)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	window->priv->logout_enabled = (logout_enabled != FALSE);
+}
+
+void
+gs_window_set_user_switch_enabled (GSWindow *window,
+                                   gboolean  user_switch_enabled)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	window->priv->user_switch_enabled = (user_switch_enabled != FALSE);
+}
+
+void
+gs_window_set_logout_timeout (GSWindow *window,
+                              glong     logout_timeout)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	if (logout_timeout < 0)
+	{
+		window->priv->logout_timeout = 0;
+	}
+	else
+	{
+		window->priv->logout_timeout = logout_timeout;
+	}
+}
+
+void
+gs_window_set_logout_command (GSWindow   *window,
+                              const char *command)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	g_free (window->priv->logout_command);
+
+	if (command)
+	{
+		window->priv->logout_command = g_strdup (command);
+	}
+	else
+	{
+		window->priv->logout_command = NULL;
+	}
+}
+
+void
+gs_window_set_status_message (GSWindow   *window,
+                              const char *status_message)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	g_free (window->priv->status_message);
+	window->priv->status_message = g_strdup (status_message);
+}
+
+void
+gs_window_set_monitor (GSWindow   *window,
+                       GdkMonitor *monitor)
+{
+	g_return_if_fail (GS_IS_WINDOW (window));
+
+	if (window->priv->monitor == monitor)
+	{
+		return;
+	}
+
+	window->priv->monitor = monitor;
+
+	gtk_widget_queue_resize (GTK_WIDGET (window));
+
+	g_object_notify (G_OBJECT (window), "monitor");
+}
+
+GdkMonitor *
+gs_window_get_monitor (GSWindow *window)
+{
+	g_return_val_if_fail (GS_IS_WINDOW (window), NULL);
+
+	return window->priv->monitor;
+}
+
+static void
+gs_window_set_property (GObject            *object,
+                        guint               prop_id,
+                        const GValue       *value,
+                        GParamSpec         *pspec)
+{
+	GSWindow *self;
+
+	self = GS_WINDOW (object);
+
+	switch (prop_id)
+	{
+	case PROP_LOCK_ENABLED:
+		gs_window_set_lock_enabled (self, g_value_get_boolean (value));
+		break;
+	case PROP_KEYBOARD_ENABLED:
+		gs_window_set_keyboard_enabled (self, g_value_get_boolean (value));
+		break;
+	case PROP_KEYBOARD_COMMAND:
+		gs_window_set_keyboard_command (self, g_value_get_string (value));
+		break;
+	case PROP_LOGOUT_ENABLED:
+		gs_window_set_logout_enabled (self, g_value_get_boolean (value));
+		break;
+	case PROP_LOGOUT_COMMAND:
+		gs_window_set_logout_command (self, g_value_get_string (value));
+		break;
+	case PROP_STATUS_MESSAGE:
+		gs_window_set_status_message (self, g_value_get_string (value));
+		break;
+	case PROP_LOGOUT_TIMEOUT:
+		gs_window_set_logout_timeout (self, g_value_get_long (value));
+		break;
+	case PROP_MONITOR:
+		gs_window_set_monitor (self, g_value_get_pointer (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gs_window_get_property (GObject    *object,
+                        guint       prop_id,
+                        GValue     *value,
+                        GParamSpec *pspec)
+{
+	GSWindow *self;
+
+	self = GS_WINDOW (object);
+
+	switch (prop_id)
+	{
+	case PROP_LOCK_ENABLED:
+		g_value_set_boolean (value, self->priv->lock_enabled);
+		break;
+	case PROP_KEYBOARD_ENABLED:
+		g_value_set_boolean (value, self->priv->keyboard_enabled);
+		break;
+	case PROP_KEYBOARD_COMMAND:
+		g_value_set_string (value, self->priv->keyboard_command);
+		break;
+	case PROP_LOGOUT_ENABLED:
+		g_value_set_boolean (value, self->priv->logout_enabled);
+		break;
+	case PROP_LOGOUT_COMMAND:
+		g_value_set_string (value, self->priv->logout_command);
+		break;
+	case PROP_STATUS_MESSAGE:
+		g_value_set_string (value, self->priv->status_message);
+		break;
+	case PROP_LOGOUT_TIMEOUT:
+		g_value_set_long (value, self->priv->logout_timeout);
+		break;
+	case PROP_MONITOR:
+		g_value_set_pointer (value, (gpointer) self->priv->monitor);
+		break;
+	case PROP_OBSCURED:
+		g_value_set_boolean (value, self->priv->obscured);
+		break;
+	case PROP_DIALOG_UP:
+		g_value_set_boolean (value, self->priv->dialog_up);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+queue_key_event (GSWindow    *window,
+                 GdkEventKey *event)
+{
+	/* Eat the first return, enter, escape, or space */
+	if (window->priv->key_events == NULL
+	        && (event->keyval == GDK_KEY_Return
+	            || event->keyval == GDK_KEY_KP_Enter
+	            || event->keyval == GDK_KEY_Escape
+	            || event->keyval == GDK_KEY_space))
+	{
+		return;
+	}
+
+	/* Only cache MAX_QUEUED_EVENTS key events.  If there are any more than this then
+	   something is wrong */
+	/* Don't queue keys that may cause focus navigation in the dialog */
+	if (g_list_length (window->priv->key_events) < MAX_QUEUED_EVENTS
+	        && event->keyval != GDK_KEY_Tab
+	        && event->keyval != GDK_KEY_Up
+	        && event->keyval != GDK_KEY_Down)
+	{
+		window->priv->key_events = g_list_prepend (window->priv->key_events,
+		                           gdk_event_copy ((GdkEvent *)event));
+	}
+}
+
+static gboolean
+maybe_handle_activity (GSWindow *window)
+{
+	gboolean handled;
+
+	handled = FALSE;
+
+	/* if we already have a socket then don't bother */
+	if (! window->priv->lock_socket
+	        && gtk_widget_get_sensitive (GTK_WIDGET (window)))
+	{
+		g_signal_emit (window, signals [ACTIVITY], 0, &handled);
+	}
+
+	return handled;
+}
+
+static gboolean
+gs_window_real_key_press_event (GtkWidget   *widget,
+                                GdkEventKey *event)
+{
+	/*g_message ("KEY PRESS state: %u keyval %u", event->state, event->keyval);*/
+
+	/* Ignore brightness keys */
+	if (event->hardware_keycode == 101 || event->hardware_keycode == 212)
+	{
+		gs_debug ("Ignoring brightness keys");
+		return TRUE;
+	}
+
+	maybe_handle_activity (GS_WINDOW (widget));
+
+	queue_key_event (GS_WINDOW (widget), event);
+
+	if (GTK_WIDGET_CLASS (gs_window_parent_class)->key_press_event)
+	{
+		GTK_WIDGET_CLASS (gs_window_parent_class)->key_press_event (widget, event);
+	}
+
+	return TRUE;
+}
+
+static gboolean
+gs_window_real_motion_notify_event (GtkWidget      *widget,
+                                    GdkEventMotion *event)
+{
+	GSWindow   *window;
+	gdouble     distance;
+	gdouble     min_distance;
+	gdouble     min_percentage = 0.1;
+	GdkDisplay *display;
+	GdkScreen  *screen;
+
+	window = GS_WINDOW (widget);
+
+	display = gs_window_get_display (window);
+	screen = gdk_display_get_default_screen (display);
+	min_distance = WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) * min_percentage;
+
+	/* if the last position was not set then don't detect motion */
+	if (window->priv->last_x < 0 || window->priv->last_y < 0)
+	{
+		window->priv->last_x = event->x;
+		window->priv->last_y = event->y;
+
+		return FALSE;
+	}
+
+	/* just an approximate distance */
+	distance = MAX (ABS (window->priv->last_x - event->x),
+	                ABS (window->priv->last_y - event->y));
+
+	if (distance > min_distance)
+	{
+		maybe_handle_activity (window);
+
+		window->priv->last_x = -1;
+		window->priv->last_y = -1;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+gs_window_real_button_press_event (GtkWidget      *widget,
+                                   GdkEventButton *event)
+{
+	GSWindow *window;
+
+	window = GS_WINDOW (widget);
+	maybe_handle_activity (window);
+
+	return FALSE;
+}
+
+static gboolean
+gs_window_real_scroll_event (GtkWidget      *widget,
+                             GdkEventScroll *event)
+{
+	GSWindow *window;
+
+	window = GS_WINDOW (widget);
+	maybe_handle_activity (window);
+
+	return FALSE;
+}
+
+static void
+gs_window_real_size_request (GtkWidget      *widget,
+                             GtkRequisition *requisition)
+{
+	GSWindow      *window;
+	GtkBin        *bin;
+	GtkWidget     *child;
+	GdkRectangle   old_geometry;
+	int            position_changed = FALSE;
+	int            size_changed = FALSE;
+
+	window = GS_WINDOW (widget);
+	bin = GTK_BIN (widget);
+	child = gtk_bin_get_child (bin);
+
+	if (child && gtk_widget_get_visible (child))
+	{
+		gtk_widget_get_preferred_size (child, requisition, NULL);
+	}
+
+	old_geometry = window->priv->geometry;
+
+	update_geometry (window);
+
+	requisition->width  = window->priv->geometry.width;
+	requisition->height = window->priv->geometry.height;
+
+	if (! gtk_widget_get_realized (widget))
+	{
+		return;
+	}
+
+	if (old_geometry.width  != window->priv->geometry.width ||
+	        old_geometry.height != window->priv->geometry.height)
+	{
+		size_changed = TRUE;
+	}
+
+	if (old_geometry.x != window->priv->geometry.x ||
+	        old_geometry.y != window->priv->geometry.y)
+	{
+		position_changed = TRUE;
+	}
+
+	gs_window_move_resize_window (window, position_changed, size_changed);
+}
+
+static void
+gs_window_real_get_preferred_width (GtkWidget *widget,
+                                    gint      *minimal_width,
+                                    gint      *natural_width)
+{
+	GtkRequisition requisition;
+	gs_window_real_size_request (widget, &requisition);
+	*minimal_width = *natural_width = requisition.width;
+}
+
+static void
+gs_window_real_get_preferred_height (GtkWidget *widget,
+                                     gint      *minimal_height,
+                                     gint      *natural_height)
+{
+	GtkRequisition requisition;
+	gs_window_real_size_request (widget, &requisition);
+	*minimal_height = *natural_height = requisition.height;
+}
+
+static gboolean
+gs_window_real_grab_broken (GtkWidget          *widget,
+                            GdkEventGrabBroken *event)
+{
+	if (event->grab_window != NULL)
+	{
+		gs_debug ("Grab broken on window %X %s, new grab on window %X",
+		          (guint32) GDK_WINDOW_XID (event->window),
+		          event->keyboard ? "keyboard" : "pointer",
+		          (guint32) GDK_WINDOW_XID (event->grab_window));
+	}
+	else
+	{
+		gs_debug ("Grab broken on window %X %s, new grab is outside application",
+		          (guint32) GDK_WINDOW_XID (event->window),
+		          event->keyboard ? "keyboard" : "pointer");
+	}
+
+	return FALSE;
+}
+
+gboolean
+gs_window_is_obscured (GSWindow *window)
+{
+	g_return_val_if_fail (GS_IS_WINDOW (window), FALSE);
+
+	return window->priv->obscured;
+}
+
+gboolean
+gs_window_is_dialog_up (GSWindow *window)
+{
+	g_return_val_if_fail (GS_IS_WINDOW (window), FALSE);
+
+	return window->priv->dialog_up;
+}
+
+static void
+window_set_obscured (GSWindow *window,
+                     gboolean  obscured)
+{
+	if (window->priv->obscured == obscured)
+	{
+		return;
+	}
+
+	window->priv->obscured = (obscured != FALSE);
+	g_object_notify (G_OBJECT (window), "obscured");
+}
+
+static gboolean
+gs_window_real_visibility_notify_event (GtkWidget          *widget,
+                                        GdkEventVisibility *event)
+{
+	switch (event->state)
+	{
+	case GDK_VISIBILITY_FULLY_OBSCURED:
+		window_set_obscured (GS_WINDOW (widget), TRUE);
+		break;
+	case GDK_VISIBILITY_PARTIAL:
+		break;
+	case GDK_VISIBILITY_UNOBSCURED:
+		window_set_obscured (GS_WINDOW (widget), FALSE);
+		break;
+	default:
+		break;
+	}
+
+	return FALSE;
+}
+
+static void
+gs_window_class_init (GSWindowClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+	object_class->finalize     = gs_window_finalize;
+	object_class->get_property = gs_window_get_property;
+	object_class->set_property = gs_window_set_property;
+
+	widget_class->show                = gs_window_real_show;
+	widget_class->hide                = gs_window_real_hide;
+	widget_class->draw                = gs_window_real_draw;
+	widget_class->realize             = gs_window_real_realize;
+	widget_class->unrealize           = gs_window_real_unrealize;
+	widget_class->key_press_event     = gs_window_real_key_press_event;
+	widget_class->motion_notify_event = gs_window_real_motion_notify_event;
+	widget_class->button_press_event  = gs_window_real_button_press_event;
+	widget_class->scroll_event        = gs_window_real_scroll_event;
+	widget_class->get_preferred_width  = gs_window_real_get_preferred_width;
+	widget_class->get_preferred_height = gs_window_real_get_preferred_height;
+	widget_class->grab_broken_event   = gs_window_real_grab_broken;
+	widget_class->visibility_notify_event = gs_window_real_visibility_notify_event;
+
+	signals [ACTIVITY] =
+	    g_signal_new ("activity",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSWindowClass, activity),
+	                  NULL,
+	                  NULL,
+	                  gs_marshal_BOOLEAN__VOID,
+	                  G_TYPE_BOOLEAN,
+	                  0);
+	signals [DEACTIVATED] =
+	    g_signal_new ("deactivated",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSWindowClass, deactivated),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0);
+
+	g_object_class_install_property (object_class,
+	                                 PROP_OBSCURED,
+	                                 g_param_spec_boolean ("obscured",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READABLE));
+	g_object_class_install_property (object_class,
+	                                 PROP_DIALOG_UP,
+	                                 g_param_spec_boolean ("dialog-up",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READABLE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LOCK_ENABLED,
+	                                 g_param_spec_boolean ("lock-enabled",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LOGOUT_ENABLED,
+	                                 g_param_spec_boolean ("logout-enabled",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LOGOUT_TIMEOUT,
+	                                 g_param_spec_long ("logout-timeout",
+	                                         NULL,
+	                                         NULL,
+	                                         -1,
+	                                         G_MAXLONG,
+	                                         0,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LOGOUT_COMMAND,
+	                                 g_param_spec_string ("logout-command",
+	                                         NULL,
+	                                         NULL,
+	                                         NULL,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_STATUS_MESSAGE,
+	                                 g_param_spec_string ("status-message",
+	                                         NULL,
+	                                         NULL,
+	                                         NULL,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_KEYBOARD_ENABLED,
+	                                 g_param_spec_boolean ("keyboard-enabled",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_KEYBOARD_COMMAND,
+	                                 g_param_spec_string ("keyboard-command",
+	                                         NULL,
+	                                         NULL,
+	                                         NULL,
+	                                         G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_MONITOR,
+	                                 g_param_spec_pointer ("monitor",
+	                                         "Gdk monitor",
+	                                         "The monitor (in terms of Gdk) which the window is on",
+	                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+create_info_bar (GSWindow *window)
+{
+	window->priv->info_bar = gtk_info_bar_new ();
+	gtk_widget_set_no_show_all (window->priv->info_bar, TRUE);
+	gtk_box_pack_end (GTK_BOX (window->priv->vbox), window->priv->info_bar, FALSE, FALSE, 0);
+}
+
+static gboolean
+on_drawing_area_draw (GtkWidget *widget,
+                      cairo_t   *cr)
+{
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+	cairo_set_source_rgb (cr, 0, 0, 0);
+	cairo_paint (cr);
+
+	return FALSE;
+}
+
+static void
+gs_window_init (GSWindow *window)
+{
+	window->priv = gs_window_get_instance_private (window);
+
+	window->priv->geometry.x      = -1;
+	window->priv->geometry.y      = -1;
+	window->priv->geometry.width  = -1;
+	window->priv->geometry.height = -1;
+
+	window->priv->last_x = -1;
+	window->priv->last_y = -1;
+
+	gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
+
+	gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
+	gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
+
+	gtk_window_set_keep_above (GTK_WINDOW (window), TRUE);
+
+	gtk_window_fullscreen (GTK_WINDOW (window));
+
+	gtk_widget_set_events (GTK_WIDGET (window),
+	                       gtk_widget_get_events (GTK_WIDGET (window))
+	                       | GDK_POINTER_MOTION_MASK
+	                       | GDK_BUTTON_PRESS_MASK
+	                       | GDK_BUTTON_RELEASE_MASK
+	                       | GDK_KEY_PRESS_MASK
+	                       | GDK_KEY_RELEASE_MASK
+	                       | GDK_EXPOSURE_MASK
+	                       | GDK_VISIBILITY_NOTIFY_MASK
+	                       | GDK_ENTER_NOTIFY_MASK
+	                       | GDK_LEAVE_NOTIFY_MASK);
+
+	window->priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+	gtk_widget_show (window->priv->vbox);
+	gtk_container_add (GTK_CONTAINER (window), window->priv->vbox);
+
+	window->priv->drawing_area = gtk_drawing_area_new ();
+	gtk_widget_show (window->priv->drawing_area);
+	gtk_widget_set_app_paintable (window->priv->drawing_area, TRUE);
+	gtk_box_pack_start (GTK_BOX (window->priv->vbox),
+	                    window->priv->drawing_area, TRUE, TRUE, 0);
+	g_signal_connect (window->priv->drawing_area,
+	                  "draw",
+	                  G_CALLBACK (on_drawing_area_draw),
+	                  NULL);
+	create_info_bar (window);
+
+}
+
+static void
+remove_command_watches (GSWindow *window)
+{
+	if (window->priv->lock_watch_id != 0)
+	{
+		g_source_remove (window->priv->lock_watch_id);
+		window->priv->lock_watch_id = 0;
+	}
+	if (window->priv->keyboard_watch_id != 0)
+	{
+		g_source_remove (window->priv->keyboard_watch_id);
+		window->priv->keyboard_watch_id = 0;
+	}
+}
+
+static void
+gs_window_finalize (GObject *object)
+{
+	GSWindow *window;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GS_IS_WINDOW (object));
+
+	window = GS_WINDOW (object);
+
+	g_return_if_fail (window->priv != NULL);
+
+	g_free (window->priv->logout_command);
+	g_free (window->priv->keyboard_command);
+
+	if (window->priv->info_bar_timer_id > 0)
+	{
+		g_source_remove (window->priv->info_bar_timer_id);
+		window->priv->info_bar_timer_id = 0;
+	}
+
+	remove_watchdog_timer (window);
+	remove_popup_dialog_idle (window);
+
+	if (window->priv->timer)
+	{
+		g_timer_destroy (window->priv->timer);
+	}
+
+	remove_key_events (window);
+
+	remove_command_watches (window);
+
+	gs_window_dialog_finish (window);
+
+	if (window->priv->background_surface)
+	{
+		cairo_surface_destroy (window->priv->background_surface);
+	}
+
+	G_OBJECT_CLASS (gs_window_parent_class)->finalize (object);
+}
+
+GSWindow *
+gs_window_new (GdkMonitor *monitor,
+               gboolean   lock_enabled)
+{
+	GObject    *result;
+	GdkDisplay *display = gdk_monitor_get_display (monitor);
+	GdkScreen  *screen = gdk_display_get_default_screen (display);
+
+	result = g_object_new (GS_TYPE_WINDOW,
+	                       "type", GTK_WINDOW_POPUP,
+	                       "screen", screen,
+	                       "monitor", monitor,
+	                       "lock-enabled", lock_enabled,
+	                       "app-paintable", TRUE,
+	                       NULL);
+
+	return GS_WINDOW (result);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/17.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/17.html new file mode 100644 index 0000000..9577e66 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/17.html @@ -0,0 +1,1349 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <locale.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#define GS_SERVICE   "org.mate.ScreenSaver"
+#define GS_PATH      "/org/mate/ScreenSaver"
+#define GS_INTERFACE "org.mate.ScreenSaver"
+
+static gboolean do_quit       = FALSE;
+static gboolean do_lock       = FALSE;
+static gboolean do_unlock     = FALSE;
+static gboolean do_cycle      = FALSE;
+static gboolean do_activate   = FALSE;
+static gboolean do_deactivate = FALSE;
+static gboolean do_version    = FALSE;
+static gboolean do_poke       = FALSE;
+static gboolean do_inhibit    = FALSE;
+
+static gboolean do_query      = FALSE;
+static gboolean do_time       = FALSE;
+
+static char    *inhibit_reason      = NULL;
+static char    *inhibit_application = NULL;
+
+static GOptionEntry entries [] =
+{
+	{
+		"exit", 0, 0, G_OPTION_ARG_NONE, &do_quit,
+		N_("Causes the screensaver to exit gracefully"), NULL
+	},
+	{
+		"query", 'q', 0, G_OPTION_ARG_NONE, &do_query,
+		N_("Query the state of the screensaver"), NULL
+	},
+	{
+		"time", 't', 0, G_OPTION_ARG_NONE, &do_time,
+		N_("Query the length of time the screensaver has been active"), NULL
+	},
+	{
+		"lock", 'l', 0, G_OPTION_ARG_NONE, &do_lock,
+		N_("Tells the running screensaver process to lock the screen immediately"), NULL
+	},
+	{
+		"unlock", 'u', 0, G_OPTION_ARG_NONE, &do_unlock,
+		N_("Tells the running screensaver process to unlock the screen immediately"), NULL
+	},
+	{
+		"cycle", 'c', 0, G_OPTION_ARG_NONE, &do_cycle,
+		N_("If the screensaver is active then switch to another graphics demo"), NULL
+	},
+	{
+		"activate", 'a', 0, G_OPTION_ARG_NONE, &do_activate,
+		N_("Turn the screensaver on (blank the screen)"), NULL
+	},
+	{
+		"deactivate", 'd', 0, G_OPTION_ARG_NONE, &do_deactivate,
+		N_("If the screensaver is active then deactivate it (un-blank the screen)"), NULL
+	},
+	{
+		"poke", 'p', 0, G_OPTION_ARG_NONE, &do_poke,
+		N_("Poke the running screensaver to simulate user activity"), NULL
+	},
+	{
+		"inhibit", 'i', 0, G_OPTION_ARG_NONE, &do_inhibit,
+		N_("Inhibit the screensaver from activating.  Command blocks while inhibit is active."), NULL
+	},
+	{
+		"application-name", 'n', 0, G_OPTION_ARG_STRING, &inhibit_application,
+		N_("The calling application that is inhibiting the screensaver"), NULL
+	},
+	{
+		"reason", 'r', 0, G_OPTION_ARG_STRING, &inhibit_reason,
+		N_("The reason for inhibiting the screensaver"), NULL
+	},
+	{
+		"version", 'V', 0, G_OPTION_ARG_NONE, &do_version,
+		N_("Version of this application"), NULL
+	},
+	{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
+};
+
+static GMainLoop *loop = NULL;
+
+static gboolean
+screensaver_is_running (DBusConnection *connection)
+{
+	DBusError               error;
+	gboolean                exists;
+
+	g_return_val_if_fail (connection != NULL, FALSE);
+
+	dbus_error_init (&error);
+	exists = dbus_bus_name_has_owner (connection, GS_SERVICE, &error);
+	if (dbus_error_is_set (&error))
+		dbus_error_free (&error);
+
+	return exists;
+}
+
+static DBusMessage *
+screensaver_send_message_inhibit (DBusConnection *connection,
+                                  const char     *application,
+                                  const char     *reason)
+{
+	DBusMessage    *message;
+	DBusMessage    *reply;
+	DBusError       error;
+	DBusMessageIter iter;
+
+	g_return_val_if_fail (connection != NULL, NULL);
+
+	dbus_error_init (&error);
+
+	message = dbus_message_new_method_call (GS_SERVICE, GS_PATH, GS_INTERFACE, "Inhibit");
+	if (message == NULL)
+	{
+		g_warning ("Couldn't allocate the dbus message");
+		return NULL;
+	}
+
+	dbus_message_iter_init_append (message, &iter);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &application);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reason);
+
+	reply = dbus_connection_send_with_reply_and_block (connection,
+	        message,
+	        -1, &error);
+	if (dbus_error_is_set (&error))
+	{
+		g_warning ("%s raised:\n %s\n\n", error.name, error.message);
+		reply = NULL;
+	}
+
+	dbus_connection_flush (connection);
+
+	dbus_message_unref (message);
+	dbus_error_free (&error);
+
+	return reply;
+}
+
+static DBusMessage *
+screensaver_send_message_bool (DBusConnection *connection,
+                               const char     *name,
+                               gboolean        value)
+{
+	DBusMessage    *message;
+	DBusMessage    *reply;
+	DBusError       error;
+	DBusMessageIter iter;
+
+	g_return_val_if_fail (connection != NULL, NULL);
+	g_return_val_if_fail (name != NULL, NULL);
+
+	dbus_error_init (&error);
+
+	message = dbus_message_new_method_call (GS_SERVICE, GS_PATH, GS_INTERFACE, name);
+	if (message == NULL)
+	{
+		g_warning ("Couldn't allocate the dbus message");
+		return NULL;
+	}
+
+	dbus_message_iter_init_append (message, &iter);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &value);
+
+	reply = dbus_connection_send_with_reply_and_block (connection,
+	        message,
+	        -1, &error);
+	if (dbus_error_is_set (&error))
+	{
+		g_warning ("%s raised:\n %s\n\n", error.name, error.message);
+		reply = NULL;
+	}
+
+	dbus_connection_flush (connection);
+
+	dbus_message_unref (message);
+	dbus_error_free (&error);
+
+	return reply;
+}
+
+static DBusMessage *
+screensaver_send_message_void (DBusConnection *connection,
+                               const char     *name,
+                               gboolean        expect_reply)
+{
+	DBusMessage *message;
+	DBusMessage *reply;
+	DBusError    error;
+
+	g_return_val_if_fail (connection != NULL, NULL);
+	g_return_val_if_fail (name != NULL, NULL);
+
+	dbus_error_init (&error);
+
+	message = dbus_message_new_method_call (GS_SERVICE, GS_PATH, GS_INTERFACE, name);
+	if (message == NULL)
+	{
+		g_warning ("Couldn't allocate the dbus message");
+		return NULL;
+	}
+
+	if (! expect_reply)
+	{
+		if (!dbus_connection_send (connection, message, NULL))
+			g_warning ("could not send message");
+		reply = NULL;
+	}
+	else
+	{
+		reply = dbus_connection_send_with_reply_and_block (connection,
+		        message,
+		        -1, &error);
+		if (dbus_error_is_set (&error))
+		{
+			g_warning ("%s raised:\n %s\n\n", error.name, error.message);
+			reply = NULL;
+		}
+	}
+	dbus_connection_flush (connection);
+
+	dbus_message_unref (message);
+	dbus_error_free (&error);
+
+	return reply;
+}
+
+static char **
+get_string_from_iter (DBusMessageIter *iter,
+                      int             *num_elements)
+{
+	int    count;
+	char **buffer;
+
+	if (num_elements != NULL)
+	{
+		*num_elements = 0;
+	}
+
+	count = 0;
+	buffer = (char **)malloc (sizeof (char *) * 8);
+
+	if (buffer == NULL)
+	{
+		goto oom;
+	}
+
+	buffer[0] = NULL;
+	while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING)
+	{
+		const char *value;
+		char       *str;
+
+		if ((count % 8) == 0 && count != 0)
+		{
+			buffer = realloc (buffer, sizeof (char *) * (count + 8));<--- Common realloc mistake: 'buffer' nulled but not freed upon failure
+			if (buffer == NULL)
+			{
+				goto oom;
+			}
+		}
+
+		dbus_message_iter_get_basic (iter, &value);
+		str = strdup (value);
+		if (str == NULL)
+		{
+			goto oom;
+		}
+
+		buffer[count] = str;
+
+		dbus_message_iter_next (iter);
+		count++;
+	}
+
+	if ((count % 8) == 0)
+	{
+		buffer = realloc (buffer, sizeof (char *) * (count + 1));<--- Common realloc mistake: 'buffer' nulled but not freed upon failure
+		if (buffer == NULL)
+		{
+			goto oom;
+		}
+	}
+
+	buffer[count] = NULL;
+	if (num_elements != NULL)
+	{
+		*num_elements = count;
+	}
+	return buffer;
+
+oom:
+	g_debug ("%s %d : error allocating memory\n", __FILE__, __LINE__);
+	return NULL;
+
+}
+
+static gboolean
+do_command (gpointer data)
+{
+	DBusConnection *connection = data;
+	DBusMessage *reply;
+
+	if (do_quit)
+	{
+		reply = screensaver_send_message_void (connection, "Quit", FALSE);
+		goto done;
+	}
+
+	if (do_query)
+	{
+		DBusMessageIter iter;
+		DBusMessageIter array;
+		dbus_bool_t     v;
+
+		reply = screensaver_send_message_void (connection, "GetActive", TRUE);
+		if (! reply)
+		{
+			g_message ("Did not receive a reply from the screensaver.");
+			goto done;
+		}
+
+		dbus_message_iter_init (reply, &iter);
+		dbus_message_iter_get_basic (&iter, &v);
+		g_print (_("The screensaver is %s\n"), v ? _("active") : _("inactive"));
+
+		dbus_message_unref (reply);
+
+		reply = screensaver_send_message_void (connection, "GetInhibitors", TRUE);
+		if (! reply)
+		{
+			g_message ("Did not receive a reply from screensaver.");
+			goto done;
+		}
+
+		dbus_message_iter_init (reply, &iter);
+		dbus_message_iter_recurse (&iter, &array);
+
+		if (dbus_message_iter_get_arg_type (&array) == DBUS_TYPE_INVALID)
+		{
+			g_print (_("The screensaver is not inhibited\n"));
+		}
+		else
+		{
+			char **inhibitors;
+			int    i;
+			int    num;
+
+			g_print (_("The screensaver is being inhibited by:\n"));
+			inhibitors = get_string_from_iter (&array, &num);
+			for (i = 0; i < num; i++)
+			{
+				g_print ("\t%s\n", inhibitors[i]);
+			}
+			g_strfreev (inhibitors);
+		}
+
+		dbus_message_unref (reply);
+	}
+
+	if (do_time)
+	{
+		DBusMessageIter iter;
+		dbus_bool_t     v;
+		dbus_int32_t    t;
+
+		reply = screensaver_send_message_void (connection, "GetActive", TRUE);
+		if (! reply)
+		{
+			g_message ("Did not receive a reply from the screensaver.");
+			goto done;
+		}
+
+		dbus_message_iter_init (reply, &iter);
+		dbus_message_iter_get_basic (&iter, &v);
+		dbus_message_unref (reply);
+
+		if (v)
+		{
+
+			reply = screensaver_send_message_void (connection, "GetActiveTime", TRUE);
+			dbus_message_iter_init (reply, &iter);
+			dbus_message_iter_get_basic (&iter, &t);
+			g_print (_("The screensaver has been active for %d seconds.\n"), t);
+
+			dbus_message_unref (reply);
+		}
+		else
+		{
+			g_print (_("The screensaver is not currently active.\n"));
+		}
+	}
+
+	if (do_lock)
+	{
+		reply = screensaver_send_message_void (connection, "Lock", FALSE);
+	}
+
+	if (do_unlock)
+	{
+		reply = screensaver_send_message_void (connection, "Unlock", FALSE);
+	}
+
+	if (do_cycle)
+	{
+		reply = screensaver_send_message_void (connection, "Cycle", FALSE);
+	}
+
+	if (do_poke)
+	{
+		reply = screensaver_send_message_void (connection, "SimulateUserActivity", FALSE);
+	}
+
+	if (do_activate)
+	{
+		reply = screensaver_send_message_bool (connection, "SetActive", TRUE);
+		if (! reply)
+		{
+			g_message ("Did not receive a reply from the screensaver.");
+			goto done;
+		}
+		dbus_message_unref (reply);
+	}
+
+	if (do_deactivate)
+	{
+		reply = screensaver_send_message_bool (connection, "SetActive", FALSE);
+		if (! reply)
+		{
+			g_message ("Did not receive a reply from the screensaver.");
+			goto done;
+		}
+		dbus_message_unref (reply);
+	}
+
+	if (do_inhibit)
+	{
+		reply = screensaver_send_message_inhibit (connection,
+		        inhibit_application ? inhibit_application : "Unknown",
+		        inhibit_reason ? inhibit_reason : "Unknown");
+		if (! reply)
+		{
+			g_message ("Did not receive a reply from the screensaver.");
+			goto done;
+		}
+		dbus_message_unref (reply);
+
+		return FALSE;
+	}
+
+done:
+	g_main_loop_quit (loop);
+
+	return FALSE;
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+	DBusConnection *connection;
+	DBusError       dbus_error;
+	GOptionContext *context;
+	gboolean        retval;
+	GError         *error = NULL;
+
+#ifdef ENABLE_NLS
+	bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
+# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+# endif
+	textdomain (GETTEXT_PACKAGE);
+#endif
+
+	g_set_prgname (argv[0]);
+
+	if (setlocale (LC_ALL, "") == NULL)
+		g_warning ("Locale not understood by C library, internationalization will not work\n");
+
+	context = g_option_context_new (NULL);
+	g_option_context_add_main_entries (context, entries, NULL);
+	retval = g_option_context_parse (context, &argc, &argv, &error);
+
+	g_option_context_free (context);
+
+	if (! retval)
+	{
+		g_warning ("%s", error->message);
+		g_error_free (error);
+		exit (1);
+	}
+
+	if (do_version)
+	{
+		g_print ("%s %s\n", argv [0], VERSION);
+		exit (1);
+	}
+
+	dbus_error_init (&dbus_error);
+	connection = dbus_bus_get (DBUS_BUS_SESSION, &dbus_error);
+	if (! connection)
+	{
+		g_message ("Failed to connect to the D-BUS daemon: %s", dbus_error.message);
+		dbus_error_free (&dbus_error);
+		exit (1);
+	}
+
+	dbus_connection_setup_with_g_main (connection, NULL);
+
+	if (! screensaver_is_running (connection))
+	{
+		g_message ("Screensaver is not running!");
+		exit (1);
+	}
+
+	g_idle_add (do_command, connection);
+
+	loop = g_main_loop_new (NULL, FALSE);
+	g_main_loop_run (loop);
+
+	return 0;
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/18.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/18.html new file mode 100644 index 0000000..33ae1bd --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/18.html @@ -0,0 +1,977 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
#include <gio/gio.h>
+
+#if defined (__ELF__) && ( __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6))
+# define SECTION __attribute__ ((section (".gresource.screensaver"), aligned (8)))
+#else
+# define SECTION
+#endif
+
+static const SECTION union { const guint8 data[2660]; const double alignment; void * const ptr;}  screensaver_resource_data = { {<--- union member 'Anonymous0::alignment' is never used.<--- union member 'Anonymous0::ptr' is never used.
+  0107, 0126, 0141, 0162, 0151, 0141, 0156, 0164, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 
+  0030, 0000, 0000, 0000, 0254, 0000, 0000, 0000, 0000, 0000, 0000, 0050, 0005, 0000, 0000, 0000, 
+  0000, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 0004, 0000, 0000, 0000, 0004, 0000, 0000, 0000, 
+  0004, 0000, 0000, 0000, 0113, 0120, 0220, 0013, 0002, 0000, 0000, 0000, 0254, 0000, 0000, 0000, 
+  0004, 0000, 0114, 0000, 0260, 0000, 0000, 0000, 0264, 0000, 0000, 0000, 0201, 0321, 0040, 0031, 
+  0000, 0000, 0000, 0000, 0264, 0000, 0000, 0000, 0005, 0000, 0114, 0000, 0274, 0000, 0000, 0000, 
+  0300, 0000, 0000, 0000, 0324, 0265, 0002, 0000, 0377, 0377, 0377, 0377, 0300, 0000, 0000, 0000, 
+  0001, 0000, 0114, 0000, 0304, 0000, 0000, 0000, 0310, 0000, 0000, 0000, 0361, 0155, 0236, 0015, 
+  0001, 0000, 0000, 0000, 0310, 0000, 0000, 0000, 0014, 0000, 0114, 0000, 0324, 0000, 0000, 0000, 
+  0330, 0000, 0000, 0000, 0317, 0360, 0335, 0020, 0003, 0000, 0000, 0000, 0330, 0000, 0000, 0000, 
+  0016, 0000, 0166, 0000, 0350, 0000, 0000, 0000, 0143, 0012, 0000, 0000, 0157, 0162, 0147, 0057, 
+  0001, 0000, 0000, 0000, 0155, 0141, 0164, 0145, 0057, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 
+  0057, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0163, 0143, 0162, 0145, 0145, 0156, 0163, 0141, 
+  0166, 0145, 0162, 0057, 0004, 0000, 0000, 0000, 0160, 0162, 0145, 0146, 0145, 0162, 0145, 0156, 
+  0143, 0145, 0163, 0056, 0165, 0151, 0000, 0000, 0105, 0170, 0000, 0000, 0001, 0000, 0000, 0000, 
+  0170, 0332, 0355, 0035, 0333, 0162, 0333, 0066, 0366, 0275, 0137, 0301, 0345, 0103, 0137, 0166, 
+  0144, 0131, 0262, 0235, 0355, 0246, 0266, 0072, 0111, 0263, 0311, 0164, 0246, 0235, 0351, 0154, 
+  0322, 0315, 0043, 0007, 0042, 0217, 0110, 0304, 0020, 0301, 0005, 0100, 0311, 0372, 0373, 0002, 
+  0244, 0054, 0223, 0026, 0157, 0000, 0111, 0213, 0162, 0370, 0220, 0211, 0045, 0342, 0000, 0007, 
+  0347, 0176, 0001, 0250, 0333, 0137, 0036, 0326, 0304, 0332, 0000, 0343, 0230, 0206, 0167, 0366, 
+  0354, 0342, 0322, 0266, 0040, 0164, 0251, 0207, 0103, 0377, 0316, 0376, 0353, 0313, 0307, 0311, 
+  0117, 0366, 0057, 0213, 0037, 0156, 0377, 0061, 0231, 0130, 0237, 0040, 0004, 0206, 0004, 0170, 
+  0326, 0026, 0213, 0300, 0362, 0011, 0362, 0300, 0272, 0272, 0230, 0317, 0057, 0346, 0326, 0144, 
+  0042, 0007, 0341, 0120, 0000, 0133, 0041, 0027, 0026, 0077, 0130, 0326, 0055, 0203, 0377, 0307, 
+  0230, 0001, 0267, 0010, 0136, 0336, 0331, 0276, 0270, 0377, 0247, 0375, 0264, 0320, 0325, 0305, 
+  0354, 0332, 0236, 0046, 0343, 0324, 0324, 0007, 0310, 0011, 0301, 0056, 0204, 0034, 0046, 0142, 
+  0027, 0201, 0345, 0107, 0144, 0223, 0316, 0175, 0064, 0056, 0104, 0153, 0260, 0326, 0022, 0233, 
+  0011, 0167, 0031, 0110, 0020, 0044, 0347, 0056, 0036, 0352, 0201, 0034, 0202, 0043, 0041, 0027, 
+  0266, 0262, 0203, 0043, 0006, 0053, 0140, 0162, 0267, 0022, 0307, 0102, 0100, 0227, 0106, 0073, 
+  0206, 0375, 0100, 0130, 0177, 0274, 0373, 0362, 0037, 0353, 0003, 0154, 0200, 0320, 0250, 0154, 
+  0031, 0024, 0213, 0200, 0062, 0156, 0175, 0245, 0144, 0345, 0243, 0320, 0267, 0376, 0042, 0113, 
+  0206, 0335, 0340, 0161, 0064, 0135, 0176, 0003, 0127, 0130, 0056, 0101, 0234, 0337, 0331, 0237, 
+  0304, 0375, 0073, 0357, 0133, 0314, 0305, 0032, 0102, 0141, 0133, 0330, 0273, 0263, 0321, 0341, 
+  0363, 0314, 0126, 0020, 0022, 0046, 0142, 0152, 0075, 0261, 0263, 0324, 0166, 0357, 0154, 0102, 
+  0267, 0300, 0354, 0305, 0354, 0166, 0372, 0370, 0240, 0170, 0134, 0034, 0105, 0311, 0270, 0371, 
+  0145, 0335, 0310, 0015, 0042, 0061, 0310, 0221, 0265, 0003, 0271, 0200, 0310, 0301, 0241, 0044, 
+  0137, 0202, 0160, 0075, 0016, 0021, 0362, 0041, 0007, 0360, 0154, 0211, 0333, 0151, 0112, 0220, 
+  0142, 0332, 0174, 0305, 0241, 0107, 0267, 0051, 0135, 0126, 0061, 0041, 0051, 0337, 0034, 0311, 
+  0262, 0015, 0206, 0255, 0263, 0115, 0037, 0027, 0257, 0354, 0242, 0320, 0131, 0121, 0067, 0346, 
+  0366, 0342, 0013, 0213, 0241, 0016, 0321, 0000, 0161, 0235, 0341, 0002, 0013, 0002, 0266, 0045, 
+  0030, 0012, 0071, 0101, 0002, 0055, 0211, 0374, 0162, 0007, 0022, 0372, 0163, 0106, 0266, 0376, 
+  0114, 0021, 0255, 0233, 0154, 0115, 0075, 0104, 0232, 0255, 0233, 0156, 0331, 0211, 0050, 0307, 
+  0112, 0222, 0355, 0205, 0324, 0023, 0051, 0172, 0165, 0140, 0122, 0370, 0005, 0243, 0073, 0107, 
+  0251, 0254, 0023, 0041, 0226, 0360, 0242, 0311, 0172, 0374, 0036, 0107, 0216, 0100, 0374, 0176, 
+  0211, 0230, 0023, 0140, 0055, 0060, 0305, 0173, 0035, 0040, 0017, 0134, 0232, 0130, 0026, 0173, 
+  0361, 0021, 0021, 0176, 0074, 0336, 0015, 0060, 0361, 0054, 0145, 0023, 0366, 0014, 0220, 0110, 
+  0355, 0271, 0257, 0146, 0043, 0122, 0377, 0002, 0112, 0074, 0140, 0323, 0075, 0300, 0064, 0201, 
+  0310, 0102, 0037, 0106, 0037, 0311, 0332, 0173, 0372, 0220, 0012, 0332, 0146, 0111, 0037, 0146, 
+  0227, 0207, 0171, 0013, 0264, 0005, 0163, 0054, 0371, 0135, 0274, 0251, 0032, 0121, 0054, 0334, 
+  0130, 0021, 0014, 0145, 0130, 0062, 0011, 0245, 0114, 0226, 0262, 0044, 0260, 0213, 0110, 0041, 
+  0140, 0156, 0137, 0065, 0173, 0013, 0344, 0336, 0376, 0155, 0147, 0007, 0033, 0154, 0317, 0164, 
+  0213, 0305, 0330, 0026, 0143, 0374, 0333, 0132, 0012, 0117, 0212, 0063, 0126, 0177, 0316, 0355, 
+  0347, 0060, 0206, 0210, 0267, 0101, 0276, 0120, 0167, 0021, 0363, 0161, 0350, 0020, 0130, 0111, 
+  0051, 0277, 0061, 0200, 0114, 0134, 0213, 0046, 0050, 0027, 0324, 0275, 0267, 0027, 0322, 0233, 
+  0116, 0074, 0214, 0010, 0365, 0047, 0133, 0304, 0102, 0351, 0254, 0313, 0047, 0311, 0032, 0332, 
+  0374, 0324, 0310, 0275, 0227, 0220, 0365, 0213, 0302, 0103, 0204, 0102, 0317, 0200, 0104, 0053, 
+  0114, 0210, 0001, 0330, 0223, 0215, 0273, 0254, 0332, 0126, 0041, 0376, 0071, 0315, 0327, 0225, 
+  0275, 0337, 0321, 0022, 0110, 0052, 0173, 0104, 0375, 0071, 0273, 0031, 0252, 0360, 0005, 0210, 
+  0140, 0137, 0022, 0210, 0013, 0304, 0204, 0026, 0340, 0043, 0063, 0165, 0261, 0045, 0051, 0155, 
+  0012, 0374, 0336, 0217, 0104, 0374, 0274, 0374, 0321, 0027, 0077, 0177, 0316, 0007, 0127, 0312, 
+  0001, 0252, 0147, 0323, 0344, 0241, 0316, 0132, 0061, 0007, 0107, 0052, 0311, 0175, 0034, 0351, 
+  0343, 0251, 0142, 0050, 0274, 0332, 0331, 0013, 0045, 0174, 0072, 0200, 0133, 0206, 0152, 0227, 
+  0073, 0271, 0056, 0351, 0122, 0343, 0111, 0225, 0146, 0047, 0123, 0245, 0202, 0370, 0115, 0004, 
+  0062, 0052, 0164, 0122, 0221, 0032, 0204, 0206, 0165, 0307, 0130, 0135, 0034, 0333, 0362, 0165, 
+  0376, 0262, 0174, 0175, 0037, 0013, 0041, 0227, 0055, 0143, 0154, 0362, 0077, 0215, 0271, 0263, 
+  0114, 0307, 0275, 0014, 0163, 0165, 0101, 0031, 0270, 0200, 0067, 0300, 0035, 0017, 0126, 0050, 
+  0046, 0242, 0211, 0072, 0026, 0322, 0247, 0131, 0010, 0123, 0344, 0105, 0132, 0221, 0242, 0255, 
+  0067, 0251, 0211, 0054, 0174, 0072, 0131, 0112, 0301, 0251, 0236, 0241, 0114, 0143, 0112, 0344, 
+  0353, 0274, 0343, 0220, 0253, 0101, 0051, 0131, 0010, 0017, 0142, 0124, 0260, 0214, 0202, 0135, 
+  0237, 0237, 0202, 0255, 0050, 0223, 0221, 0273, 0067, 0352, 0330, 0101, 0307, 0256, 0007, 0245, 
+  0143, 0056, 0241, 0034, 0354, 0246, 0141, 0161, 0302, 0125, 0002, 0062, 0362, 0235, 0074, 0315, 
+  0245, 0103, 0206, 0163, 0121, 0322, 0202, 0100, 0175, 0057, 0327, 0003, 0017, 0234, 0133, 0010, 
+  0346, 0115, 0027, 0202, 0131, 0104, 0200, 0342, 0315, 0033, 0155, 0334, 0140, 0323, 0332, 0131, 
+  0167, 0301, 0146, 0217, 0066, 0332, 0244, 0046, 0365, 0201, 0241, 0255, 0234, 0345, 0035, 0003, 
+  0124, 0252, 0176, 0110, 0075, 0354, 0241, 0132, 0205, 0042, 0125, 0235, 0304, 0141, 0222, 0277, 
+  0366, 0121, 0350, 0152, 0317, 0147, 0035, 0234, 0352, 0223, 0007, 0355, 0204, 0260, 0236, 0313, 
+  0371, 0055, 0146, 0036, 0126, 0227, 0364, 0077, 0142, 0002, 0362, 0237, 0000, 0226, 0162, 0075, 
+  0302, 0256, 0210, 0031, 0070, 0162, 0017, 0260, 0112, 0277, 0237, 0026, 0103, 0146, 0334, 0175, 
+  0244, 0072, 0040, 0116, 0342, 0364, 0353, 0253, 0377, 0305, 0265, 0344, 0162, 0267, 0374, 0055, 
+  0136, 0107, 0023, 0101, 0165, 0372, 0024, 0131, 0324, 0366, 0242, 0333, 0023, 0162, 0145, 0176, 
+  0245, 0032, 0277, 0017, 0111, 0221, 0360, 0200, 0340, 0112, 0032, 0373, 0364, 0233, 0222, 0166, 
+  0120, 0225, 0116, 0265, 0335, 0314, 0222, 0062, 0117, 0062, 0157, 0213, 0075, 0021, 0024, 0130, 
+  0125, 0343, 0106, 0313, 0143, 0023, 0257, 0276, 0313, 0220, 0270, 0271, 0107, 0004, 0336, 0134, 
+  0136, 0066, 0205, 0010, 0040, 0055, 0325, 0136, 0327, 0203, 0250, 0036, 0305, 0276, 0363, 0221, 
+  0122, 0272, 0217, 0136, 0106, 0332, 0165, 0014, 0021, 0231, 0044, 0037, 0323, 0316, 0205, 0335, 
+  0240, 0303, 0261, 0257, 0031, 0047, 0215, 0216, 0363, 0351, 0163, 0074, 0127, 0012, 0151, 0240, 
+  0244, 0175, 0052, 0051, 0175, 0224, 0120, 0010, 0271, 0152, 0241, 0143, 0277, 0122, 0026, 0030, 
+  0076, 0047, 0131, 0006, 0176, 0166, 0322, 0066, 0312, 0121, 0374, 0271, 0243, 0261, 0220, 0101, 
+  0330, 0116, 0255, 0010, 0241, 0327, 0266, 0377, 0222, 0215, 0213, 0003, 0040, 0121, 0232, 0147, 
+  0316, 0364, 0102, 0141, 0005, 0070, 0364, 0360, 0127, 0201, 0036, 0042, 0337, 0061, 0166, 0176, 
+  0025, 0015, 0234, 0254, 0360, 0372, 0321, 0272, 0171, 0221, 0244, 0274, 0273, 0361, 0247, 0212, 
+  0070, 0054, 0347, 0017, 0024, 0112, 0267, 0256, 0216, 0062, 0214, 0162, 0135, 0075, 0305, 0076, 
+  0376, 0311, 0104, 0152, 0272, 0132, 0021, 0207, 0322, 0373, 0021, 0034, 0302, 0153, 0326, 0214, 
+  0331, 0351, 0064, 0343, 0061, 0122, 0355, 0100, 0073, 0234, 0222, 0203, 0056, 0243, 0122, 0024, 
+  0053, 0105, 0066, 0107, 0030, 0325, 0142, 0130, 0355, 0054, 0243, 0110, 0047, 0251, 0023, 0216, 
+  0322, 0077, 0206, 0072, 0335, 0364, 0210, 0116, 0122, 0046, 0324, 0252, 0037, 0111, 0134, 0034, 
+  0225, 0274, 0126, 0047, 0033, 0247, 0252, 0055, 0346, 0317, 0362, 0015, 0051, 0121, 0253, 0251, 
+  0176, 0264, 0316, 0222, 0053, 0063, 0345, 0331, 0274, 0165, 0132, 0230, 0075, 0110, 0070, 0033, 
+  0352, 0261, 0250, 0006, 0033, 0326, 0355, 0065, 0346, 0044, 0352, 0247, 0163, 0150, 0064, 0152, 
+  0211, 0114, 0055, 0045, 0337, 0324, 0102, 0226, 0022, 0263, 0366, 0144, 0120, 0122, 0302, 0343, 
+  0245, 0347, 0200, 0072, 0241, 0156, 0027, 0024, 0156, 0165, 0002, 0317, 0040, 0250, 0316, 0026, 
+  0070, 0223, 0243, 0122, 0157, 0115, 0026, 0320, 0071, 0105, 0327, 0111, 0334, 0131, 0337, 0266, 
+  0256, 0363, 0346, 0255, 0275, 0172, 0113, 0357, 0336, 0252, 0240, 0121, 0343, 0355, 0153, 0132, 
+  0367, 0146, 0312, 0224, 0063, 0313, 0157, 0006, 0257, 0103, 0225, 0273, 0053, 0336, 0341, 0047, 
+  0206, 0275, 0175, 0101, 0107, 0376, 0065, 0263, 0253, 0240, 0073, 0330, 0146, 0127, 0133, 0055, 
+  0214, 0244, 0351, 0326, 0151, 0156, 0127, 0113, 0261, 0241, 0044, 0136, 0207, 0046, 0023, 0325, 
+  0122, 0277, 0230, 0003, 0322, 0032, 0121, 0102, 0300, 0313, 0336, 0311, 0111, 0254, 0022, 0167, 
+  0370, 0376, 0121, 0376, 0102, 0116, 0357, 0014, 0152, 0231, 0036, 0325, 0342, 0324, 0364, 0054, 
+  0147, 0255, 0217, 0110, 0351, 0243, 0156, 0320, 0104, 0224, 0140, 0167, 0147, 0057, 0102, 0330, 
+  0034, 0137, 0332, 0321, 0231, 0223, 0007, 0110, 0335, 0003, 0112, 0103, 0160, 0034, 0152, 0115, 
+  0325, 0110, 0000, 0212, 0205, 0340, 0213, 0364, 0110, 0377, 0303, 0260, 0315, 0071, 0156, 0041, 
+  0277, 0124, 0365, 0014, 0273, 0311, 0234, 0035, 0362, 0276, 0143, 0376, 0027, 0237, 0223, 0107, 
+  0236, 0332, 0342, 0001, 0107, 0055, 0315, 0257, 0151, 0106, 0161, 0040, 0340, 0246, 0376, 0244, 
+  0321, 0064, 0145, 0014, 0371, 0174, 0230, 0147, 0332, 0020, 0237, 0151, 0143, 0021, 0220, 0203, 
+  0221, 0353, 0002, 0227, 0333, 0307, 0004, 0067, 0335, 0160, 0162, 0357, 0223, 0044, 0261, 0347, 
+  0276, 0305, 0231, 0204, 0071, 0352, 0270, 0233, 0014, 0165, 0020, 0363, 0101, 0034, 0113, 0117, 
+  0143, 0344, 0265, 0021, 0252, 0213, 0104, 0264, 0051, 0323, 0164, 0302, 0372, 0020, 0247, 0064, 
+  0054, 0204, 0225, 0160, 0220, 0020, 0310, 0015, 0032, 0105, 0033, 0345, 0063, 0011, 0032, 0231, 
+  0114, 0124, 0023, 0276, 0150, 0021, 0314, 0324, 0345, 0034, 0035, 0021, 0252, 0070, 0027, 0324, 
+  0204, 0024, 0032, 0307, 0176, 0372, 0014, 0010, 0132, 0135, 0310, 0071, 0251, 0040, 0316, 0316, 
+  0132, 0020, 0233, 0020, 0253, 0031, 0241, 0114, 0157, 0175, 0264, 0277, 0001, 0322, 0131, 0172, 
+  0322, 0220, 0264, 0065, 0144, 0355, 0057, 0307, 0063, 0115, 0110, 0364, 0310, 0150, 0324, 0230, 
+  0153, 0237, 0341, 0125, 0221, 0255, 0232, 0144, 0155, 0310, 0145, 0116, 0052, 0143, 0111, 0253, 
+  0040, 0121, 0357, 0147, 0327, 0137, 0372, 0012, 0326, 0113, 0037, 0162, 0310, 0346, 0374, 0303, 
+  0271, 0036, 0155, 0132, 0123, 0275, 0171, 0275, 0065, 0325, 0066, 0305, 0234, 0253, 0327, 0130, 
+  0314, 0311, 0061, 0376, 0315, 0071, 0327, 0162, 0214, 0004, 0242, 0155, 0130, 0234, 0043, 0337, 
+  0325, 0100, 0252, 0055, 0255, 0043, 0340, 0126, 0244, 0154, 0327, 0273, 0350, 0252, 0072, 0162, 
+  0140, 0214, 0072, 0046, 0272, 0101, 0002, 0034, 0117, 0146, 0301, 0073, 0047, 0310, 0236, 0313, 
+  0035, 0106, 0161, 0304, 0254, 0216, 0141, 0326, 0147, 0153, 0107, 0346, 0332, 0366, 0321, 0063, 
+  0142, 0327, 0265, 0221, 0172, 0245, 0170, 0037, 0124, 0327, 0353, 0032, 0375, 0027, 0174, 0304, 
+  0074, 0325, 0057, 0262, 0134, 0272, 0216, 0142, 0001, 0314, 0102, 0334, 0162, 0260, 0107, 0300, 
+  0102, 0053, 0371, 0361, 0155, 0027, 0010, 0030, 0165, 0204, 0314, 0353, 0062, 0272, 0131, 0154, 
+  0147, 0035, 0244, 0216, 0073, 0112, 0235, 0247, 0160, 0006, 0231, 0262, 0131, 0025, 0260, 0245, 
+  0276, 0346, 0202, 0232, 0353, 0327, 0256, 0236, 0146, 0256, 0307, 0214, 0326, 0145, 0335, 0032, 
+  0104, 0240, 0330, 0031, 0361, 0344, 0221, 0316, 0364, 0075, 0160, 0241, 0207, 0332, 0175, 0151, 
+  0325, 0357, 0351, 0005, 0173, 0213, 0314, 0313, 0365, 0272, 0232, 0336, 0303, 0076, 0026, 0334, 
+  0110, 0141, 0115, 0154, 0240, 0231, 0035, 0354, 0252, 0150, 0325, 0175, 0021, 0253, 0127, 0213, 
+  0150, 0140, 0025, 0265, 0055, 0343, 0051, 0335, 0130, 0127, 0066, 0260, 0035, 0333, 0132, 0025, 
+  0321, 0136, 0316, 0211, 0351, 0260, 0111, 0217, 0105, 0235, 0106, 0031, 0335, 0361, 0246, 0063, 
+  0125, 0322, 0340, 0111, 0143, 0176, 0264, 0311, 0263, 0176, 0015, 0300, 0315, 0235, 0331, 0206, 
+  0120, 0105, 0300, 0216, 0253, 0276, 0067, 0317, 0265, 0052, 0216, 0142, 0275, 0333, 0373, 0320, 
+  0334, 0233, 0143, 0267, 0001, 0204, 0117, 0101, 0066, 0346, 0226, 0212, 0261, 0333, 0062, 0151, 
+  0310, 0335, 0160, 0203, 0063, 0340, 0057, 0224, 0113, 0034, 0071, 0145, 0206, 0266, 0016, 0016, 
+  0075, 0354, 0042, 0101, 0231, 0311, 0234, 0147, 0155, 0055, 0072, 0231, 0312, 0330, 0214, 0017, 
+  0336, 0134, 0020, 0352, 0336, 0367, 0150, 0054, 0176, 0227, 0323, 0357, 0015, 0105, 0152, 0043, 
+  0262, 0106, 0103, 0232, 0211, 0044, 0040, 0037, 0015, 0305, 0150, 0050, 0136, 0235, 0241, 0230, 
+  0237, 0267, 0241, 0250, 0252, 0337, 0316, 0306, 0002, 0156, 0017, 0005, 0334, 0357, 0266, 0114, 
+  0373, 0136, 0012, 0276, 0317, 0250, 0264, 0146, 0326, 0376, 0015, 0070, 0326, 0212, 0062, 0213, 
+  0074, 0271, 0216, 0267, 0337, 0161, 0075, 0265, 0373, 0114, 0364, 0065, 0227, 0123, 0157, 0306, 
+  0162, 0152, 0337, 0345, 0124, 0365, 0326, 0252, 0137, 0003, 0112, 0071, 0260, 0334, 0025, 0372, 
+  0314, 0313, 0253, 0024, 0252, 0003, 0257, 0252, 0032, 0063, 0244, 0160, 0136, 0006, 0312, 0103, 
+  0256, 0222, 0227, 0024, 0165, 0075, 0371, 0376, 0115, 0140, 0213, 0343, 0267, 0203, 0165, 0265, 
+  0102, 0305, 0173, 0245, 0222, 0343, 0324, 0126, 0306, 0102, 0377, 0126, 0167, 0117, 0177, 0054, 
+  0357, 0216, 0345, 0335, 0261, 0274, 0073, 0226, 0167, 0007, 0122, 0336, 0275, 0072, 0357, 0064, 
+  0054, 0163, 0266, 0203, 0121, 0052, 0234, 0375, 0157, 0233, 0150, 0235, 0354, 0350, 0073, 0163, 
+  0322, 0276, 0367, 0153, 0226, 0046, 0034, 0176, 0124, 0343, 0153, 0112, 0203, 0267, 0311, 0301, 
+  0216, 0307, 0332, 0222, 0024, 0035, 0053, 0244, 0302, 0132, 0102, 0222, 0070, 0200, 0227, 0344, 
+  0020, 0152, 0204, 0242, 0233, 0025, 0313, 0150, 0345, 0242, 0331, 0117, 0157, 0064, 0255, 0276, 
+  0350, 0136, 0044, 0256, 0232, 0257, 0311, 0057, 0155, 0214, 0005, 0227, 0152, 0115, 0277, 0076, 
+  0265, 0246, 0367, 0177, 0001, 0245, 0253, 0133, 0230, 0146, 0206, 0266, 0223, 0170, 0145, 0274, 
+  0302, 0322, 0033, 0171, 0307, 0053, 0054, 0047, 0172, 0111, 0301, 0170, 0205, 0145, 0270, 0077, 
+  0277, 0160, 0342, 0237, 0207, 0372, 0236, 0137, 0176, 0236, 0334, 0227, 0126, 0223, 0117, 0266, 
+  0330, 0363, 0101, 0360, 0003, 0104, 0356, 0153, 0213, 0001, 0217, 0150, 0310, 0045, 0066, 0223, 
+  0331, 0314, 0136, 0144, 0136, 0261, 0253, 0356, 0067, 0147, 0106, 0326, 0303, 0317, 0355, 0305, 
+  0323, 0113, 0116, 0265, 0241, 0377, 0145, 0057, 0252, 0026, 0176, 0366, 0045, 0317, 0277, 0153, 
+  0374, 0166, 0232, 0371, 0261, 0337, 0277, 0001, 0322, 0311, 0233, 0042, 0000, 0050, 0165, 0165, 
+  0141, 0171, 0051
+} };
+
+static GStaticResource static_resource = { screensaver_resource_data.data, sizeof (screensaver_resource_data.data) - 1 /* nul terminator */, NULL, NULL, NULL };
+
+G_MODULE_EXPORT
+GResource *screensaver_get_resource (void);
+GResource *screensaver_get_resource (void)
+{
+  return g_static_resource_get_resource (&static_resource);
+}
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __G_CONSTRUCTOR_H__
+#define __G_CONSTRUCTOR_H__
+
+/*
+  If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and
+  destructors, in a usable way, including e.g. on library unload. If not you're on
+  your own.
+
+  Some compilers need #pragma to handle this, which does not work with macros,
+  so the way you need to use this is (for constructors):
+
+  #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+  #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor)
+  #endif
+  G_DEFINE_CONSTRUCTOR(my_constructor)
+  static void my_constructor(void) {
+   ...
+  }
+
+*/
+
+#ifndef __GTK_DOC_IGNORE__
+
+#if  __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void);
+#define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void);
+
+#elif defined (_MSC_VER) && (_MSC_VER >= 1500)
+/* Visual studio 2008 and later has _Pragma */
+
+/*
+ * Only try to include gslist.h if not already included via glib.h,
+ * so that items using gconstructor.h outside of GLib (such as
+ * GResources) continue to build properly.
+ */
+#ifndef __G_LIB_H__
+#include "gslist.h"
+#endif
+
+#include <stdlib.h>
+
+#define G_HAS_CONSTRUCTORS 1
+
+/* We do some weird things to avoid the constructors being optimized
+ * away on VS2015 if WholeProgramOptimization is enabled. First we
+ * make a reference to the array from the wrapper to make sure its
+ * references. Then we use a pragma to make sure the wrapper function
+ * symbol is always included at the link stage. Also, the symbols
+ * need to be extern (but not dllexport), even though they are not
+ * really used from another object file.
+ */
+
+/* We need to account for differences between the mangling of symbols
+ * for x86 and x64/ARM/ARM64 programs, as symbols on x86 are prefixed
+ * with an underscore but symbols on x64/ARM/ARM64 are not.
+ */
+#ifdef _M_IX86
+#define G_MSVC_SYMBOL_PREFIX "_"
+#else
+#define G_MSVC_SYMBOL_PREFIX ""
+#endif
+
+#define G_DEFINE_CONSTRUCTOR(_func) G_MSVC_CTOR (_func, G_MSVC_SYMBOL_PREFIX)
+#define G_DEFINE_DESTRUCTOR(_func) G_MSVC_DTOR (_func, G_MSVC_SYMBOL_PREFIX)
+
+#define G_MSVC_CTOR(_func,_sym_prefix) \
+  static void _func(void); \
+  extern int (* _array ## _func)(void);              \
+  int _func ## _wrapper(void) { _func(); g_slist_find (NULL,  _array ## _func); return 0; } \
+  __pragma(comment(linker,"/include:" _sym_prefix # _func "_wrapper")) \
+  __pragma(section(".CRT$XCU",read)) \
+  __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _wrapper;
+
+#define G_MSVC_DTOR(_func,_sym_prefix) \
+  static void _func(void); \
+  extern int (* _array ## _func)(void);              \
+  int _func ## _constructor(void) { atexit (_func); g_slist_find (NULL,  _array ## _func); return 0; } \
+   __pragma(comment(linker,"/include:" _sym_prefix # _func "_constructor")) \
+  __pragma(section(".CRT$XCU",read)) \
+  __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _constructor;
+
+#elif defined (_MSC_VER)
+
+#define G_HAS_CONSTRUCTORS 1
+
+/* Pre Visual studio 2008 must use #pragma section */
+#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
+#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
+
+#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
+  section(".CRT$XCU",read)
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _wrapper(void) { _func(); return 0; } \
+  __declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper;
+
+#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
+  section(".CRT$XCU",read)
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _constructor(void) { atexit (_func); return 0; } \
+  __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor;
+
+#elif defined(__SUNPRO_C)
+
+/* This is not tested, but i believe it should work, based on:
+ * http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c
+ */
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
+#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
+
+#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
+  init(_func)
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void);
+
+#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
+  fini(_func)
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void);
+
+#else
+
+/* constructors not supported for this compiler */
+
+#endif
+
+#endif /* __GTK_DOC_IGNORE__ */
+#endif /* __G_CONSTRUCTOR_H__ */
+
+#ifdef G_HAS_CONSTRUCTORS
+
+#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(screensaverresource_constructor)
+#endif
+G_DEFINE_CONSTRUCTOR(screensaverresource_constructor)
+#ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA
+#pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(screensaverresource_destructor)
+#endif
+G_DEFINE_DESTRUCTOR(screensaverresource_destructor)
+
+#else
+#warning "Constructor not supported on this compiler, linking in resources will not work"
+#endif
+
+static void screensaverresource_constructor (void)
+{
+  g_static_resource_init (&static_resource);
+}
+
+static void screensaverresource_destructor (void)
+{
+  g_static_resource_fini (&static_resource);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/19.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/19.html new file mode 100644 index 0000000..6d2f199 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/19.html @@ -0,0 +1,3891 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *          Rodrigo Moya <rodrigo@novell.com>
+ *
+ */
+
+#include "config.h"
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>          /* For uid_t, gid_t */
+
+#include <glib/gi18n.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include <gio/gio.h>
+
+#define MATE_DESKTOP_USE_UNSTABLE_API
+#include <libmate-desktop/mate-desktop-utils.h>
+#include <libmate-desktop/mate-desktop-thumbnail.h>
+
+#include "gs-debug.h"
+
+#include "copy-theme-dialog.h"
+
+#include "gs-theme-manager.h"
+#include "gs-job.h"
+#include "gs-prefs.h" /* for GS_MODE enum */
+
+#define LOCKDOWN_SETTINGS_SCHEMA "org.mate.lockdown"
+#define KEY_LOCK_DISABLE "disable-lock-screen"
+
+#define SESSION_SETTINGS_SCHEMA "org.mate.session"
+#define KEY_IDLE_DELAY "idle-delay"
+
+#define GSETTINGS_SCHEMA "org.mate.screensaver"
+#define KEY_LOCK "lock-enabled"
+#define KEY_IDLE_ACTIVATION_ENABLED "idle-activation-enabled"
+#define KEY_MODE "mode"
+#define KEY_LOCK_DELAY "lock-delay"
+#define KEY_CYCLE_DELAY "cycle-delay"
+#define KEY_THEMES "themes"
+
+#define GPM_COMMAND "mate-power-preferences"
+
+enum
+{
+    NAME_COLUMN = 0,
+    ID_COLUMN,
+    N_COLUMNS
+};
+
+/* Drag and drop info */
+enum
+{
+    TARGET_URI_LIST,
+    TARGET_NS_URL
+};
+
+static GtkTargetEntry drop_types [] =
+{
+	{ "text/uri-list", 0, TARGET_URI_LIST },
+	{ "_NETSCAPE_URL", 0, TARGET_NS_URL }
+};
+
+static GtkBuilder     *builder = NULL;
+static GSThemeManager *theme_manager = NULL;
+static GSJob          *job = NULL;
+static GSettings      *screensaver_settings = NULL;
+static GSettings      *session_settings = NULL;
+static GSettings      *lockdown_settings = NULL;
+static MateDesktopThumbnailFactory *thumb_factory = NULL;
+
+static gdouble
+config_get_activate_delay (gboolean *is_writable)
+{
+	gint delay;
+
+	if (is_writable)
+	{
+		*is_writable = g_settings_is_writable (session_settings,
+		               KEY_IDLE_DELAY);
+	}
+
+	if ((delay = g_settings_get_int (session_settings, KEY_IDLE_DELAY)) < 1)
+	{
+		return 1.0;
+	}
+
+	return (gdouble) delay;
+}
+
+static void
+config_set_activate_delay (gint32 timeout)
+{
+	g_settings_set_int (session_settings, KEY_IDLE_DELAY, timeout);
+}
+
+static int
+config_get_mode (gboolean *is_writable)
+{
+	int mode;
+
+	if (is_writable)
+	{
+		*is_writable = g_settings_is_writable (screensaver_settings,
+		               KEY_MODE);
+	}
+
+	mode = g_settings_get_enum (screensaver_settings, KEY_MODE);
+
+	return mode;
+}
+
+static void
+config_set_mode (int mode)
+{
+	g_settings_set_enum (screensaver_settings, KEY_MODE, mode);
+}
+
+static char *
+config_get_theme (gboolean *is_writable)
+{
+	char *name;
+	int   mode;
+
+	if (is_writable)
+	{
+		gboolean can_write_theme;
+		gboolean can_write_mode;
+
+		can_write_theme = g_settings_is_writable (screensaver_settings,
+		                                          KEY_THEMES);
+		can_write_mode = g_settings_is_writable (screensaver_settings,
+		                                         KEY_MODE);
+		*is_writable = can_write_theme && can_write_mode;
+	}
+
+	mode = config_get_mode (NULL);
+
+	name = NULL;
+	if (mode == GS_MODE_BLANK_ONLY)
+	{
+		name = g_strdup ("__blank-only");
+	}
+	else if (mode == GS_MODE_RANDOM)
+	{
+		name = g_strdup ("__random");
+	}
+	else
+	{
+		gchar **strv;
+		strv = g_settings_get_strv (screensaver_settings,
+	                                KEY_THEMES);
+		if (strv != NULL) {
+			name = g_strdup (strv[0]);
+		}
+		else
+		{
+			/* TODO: handle error */
+			/* default to blank */
+			name = g_strdup ("__blank-only");
+		}
+
+		g_strfreev (strv);
+	}
+
+	return name;
+}
+
+static gchar **
+get_all_theme_ids (void)
+{
+	gchar **ids = NULL;
+	GSList *entries;
+	GSList *l;
+        guint idx = 0;
+
+	entries = gs_theme_manager_get_info_list (theme_manager);
+        ids = g_new0 (gchar *, g_slist_length (entries) + 1);
+	for (l = entries; l; l = l->next)
+	{
+		GSThemeInfo *info = l->data;
+
+		ids[idx++] = g_strdup (gs_theme_info_get_id (info));
+		gs_theme_info_unref (info);
+	}
+	g_slist_free (entries);
+
+	return ids;
+}
+
+static void
+config_set_theme (const char *theme_id)
+{
+	gchar **strv = NULL;
+	int     mode;
+
+	if (theme_id && strcmp (theme_id, "__blank-only") == 0)
+	{
+		mode = GS_MODE_BLANK_ONLY;
+	}
+	else if (theme_id && strcmp (theme_id, "__random") == 0)
+	{
+		mode = GS_MODE_RANDOM;
+
+		/* set the themes key to contain all available screensavers */
+		strv = get_all_theme_ids ();
+	}
+	else
+	{
+		mode = GS_MODE_SINGLE;
+		strv = g_strsplit (theme_id, "%%%", 1);
+	}
+
+	config_set_mode (mode);
+
+	g_settings_set_strv (screensaver_settings,
+	                     KEY_THEMES,
+	                     (const gchar * const*) strv);
+
+	g_strfreev (strv);
+
+}
+
+static gboolean
+config_get_enabled (gboolean *is_writable)
+{
+	int enabled;
+
+	if (is_writable)
+	{
+		*is_writable = g_settings_is_writable (screensaver_settings,
+		               KEY_LOCK);
+	}
+
+	enabled = g_settings_get_boolean (screensaver_settings, KEY_IDLE_ACTIVATION_ENABLED);
+
+	return enabled;
+}
+
+static void
+config_set_enabled (gboolean enabled)
+{
+	g_settings_set_boolean (screensaver_settings, KEY_IDLE_ACTIVATION_ENABLED, enabled);
+}
+
+static gboolean
+config_get_lock (gboolean *is_writable)
+{
+	gboolean lock;
+
+	if (is_writable)
+	{
+		*is_writable = g_settings_is_writable (screensaver_settings,
+		               KEY_LOCK);
+	}
+
+	lock = g_settings_get_boolean (screensaver_settings, KEY_LOCK);
+
+	return lock;
+}
+
+static gboolean
+config_get_lock_disabled (void)
+{
+	return g_settings_get_boolean (lockdown_settings, KEY_LOCK_DISABLE);
+}
+
+static void
+config_set_lock (gboolean lock)
+{
+	g_settings_set_boolean (screensaver_settings, KEY_LOCK, lock);
+}
+
+static void
+job_set_theme (const char *theme)
+{
+	GSThemeInfo *info;
+	const char  *command;
+
+	command = NULL;
+
+	info = gs_theme_manager_lookup_theme_info (theme_manager, theme);
+	if (info != NULL)
+	{
+		command = gs_theme_info_get_exec (info);
+	}
+
+	gs_job_set_command (job, command);
+
+	if (info != NULL)
+	{
+		gs_theme_info_unref (info);
+	}
+}
+
+static gboolean
+preview_on_draw (GtkWidget *widget,
+                 cairo_t   *cr,
+                 gpointer   data)
+{
+	if (job == NULL || !gs_job_is_running (job))
+	{
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+		cairo_set_source_rgb (cr, 0, 0, 0);
+		cairo_paint (cr);
+	}
+
+	return FALSE;
+}
+
+static void
+preview_set_theme (GtkWidget  *widget,
+                   const char *theme,
+                   const char *name)
+{
+	GtkWidget *label;
+	char      *markup;
+
+	if (job != NULL)
+	{
+		gs_job_stop (job);
+	}
+
+	gtk_widget_queue_draw (widget);
+
+	label = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_theme_label"));
+	markup = g_markup_printf_escaped ("<i>%s</i>", name);
+	gtk_label_set_markup (GTK_LABEL (label), markup);
+	g_free (markup);
+
+	if ((theme && strcmp (theme, "__blank-only") == 0))
+	{
+
+	}
+	else if (theme && strcmp (theme, "__random") == 0)
+	{
+		gchar **themes;
+
+		themes = get_all_theme_ids ();
+		if (themes != NULL)
+		{
+			gint32  i;
+
+			i = g_random_int_range (0, g_strv_length (themes));
+                        job_set_theme (themes[i]);
+                        g_strfreev (themes);
+
+			gs_job_start (job);
+		}
+	}
+	else
+	{
+		job_set_theme (theme);
+		gs_job_start (job);
+	}
+}
+
+static void
+help_display (void)
+{
+	GError *error;
+
+	error = NULL;
+	gtk_show_uri_on_window (NULL,
+                                "help:mate-user-guide/prefs-screensaver",
+                                GDK_CURRENT_TIME,
+                                &error);
+
+	if (error != NULL)
+	{
+		GtkWidget *d;
+
+		d = gtk_message_dialog_new (NULL,
+		                            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+		                            GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+		                            "%s", error->message);
+		gtk_dialog_run (GTK_DIALOG (d));
+		gtk_widget_destroy (d);
+		g_error_free (error);
+	}
+
+}
+
+static void
+response_cb (GtkWidget *widget,
+             int        response_id)
+{
+
+	if (response_id == GTK_RESPONSE_HELP)
+	{
+		help_display ();
+	}
+	else if (response_id == GTK_RESPONSE_REJECT)
+	{
+		GError  *error;
+		gboolean res;
+
+		error = NULL;
+
+		res = mate_gdk_spawn_command_line_on_screen (gdk_screen_get_default (),
+		                                        GPM_COMMAND,
+		                                        &error);
+		if (! res)
+		{
+			g_warning ("Unable to start power management preferences: %s", error->message);
+			g_error_free (error);
+		}
+	}
+	else
+	{
+		gtk_widget_destroy (widget);
+		gtk_main_quit ();
+	}
+}
+
+static GSList *
+get_theme_info_list (void)
+{
+	return gs_theme_manager_get_info_list (theme_manager);
+}
+
+static void
+populate_model (GtkTreeStore *store)
+{
+	GtkTreeIter iter;
+	GSList     *themes        = NULL;
+	GSList     *l;
+
+	gtk_tree_store_append (store, &iter, NULL);
+	gtk_tree_store_set (store, &iter,
+	                    NAME_COLUMN, _("Blank screen"),
+	                    ID_COLUMN, "__blank-only",
+	                    -1);
+
+	gtk_tree_store_append (store, &iter, NULL);
+	gtk_tree_store_set (store, &iter,
+	                    NAME_COLUMN, _("Random"),
+	                    ID_COLUMN, "__random",
+	                    -1);
+
+	gtk_tree_store_append (store, &iter, NULL);
+	gtk_tree_store_set (store, &iter,
+	                    NAME_COLUMN, NULL,
+	                    ID_COLUMN, "__separator",
+	                    -1);
+
+	themes = get_theme_info_list ();
+
+	if (themes == NULL)
+	{
+		return;
+	}
+
+	for (l = themes; l; l = l->next)
+	{
+		const char  *name;
+		const char  *id;
+		GSThemeInfo *info = l->data;
+
+		if (info == NULL)
+		{
+			continue;
+		}
+
+		name = gs_theme_info_get_name (info);
+		id = gs_theme_info_get_id (info);
+
+		gtk_tree_store_append (store, &iter, NULL);
+		gtk_tree_store_set (store, &iter,
+		                    NAME_COLUMN, name,
+		                    ID_COLUMN, id,
+		                    -1);
+
+		gs_theme_info_unref (info);
+	}
+
+	g_slist_free (themes);
+}
+
+static void
+tree_selection_previous (GtkTreeSelection *selection)
+{
+	GtkTreeIter   iter;
+	GtkTreeModel *model;
+	GtkTreePath  *path;
+
+	if (! gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		return;
+	}
+
+	path = gtk_tree_model_get_path (model, &iter);
+	if (gtk_tree_path_prev (path))
+	{
+		gtk_tree_selection_select_path (selection, path);
+	}
+}
+
+static void
+tree_selection_next (GtkTreeSelection *selection)
+{
+	GtkTreeIter   iter;
+	GtkTreeModel *model;
+	GtkTreePath  *path;
+
+	if (! gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		return;
+	}
+
+	path = gtk_tree_model_get_path (model, &iter);
+	gtk_tree_path_next (path);
+	gtk_tree_selection_select_path (selection, path);
+}
+
+static void
+tree_selection_changed_cb (GtkTreeSelection *selection,
+                           GtkWidget        *preview)
+{
+	GtkTreeIter   iter;
+	GtkTreeModel *model;
+	char         *theme;
+	char         *name;
+
+	if (! gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		return;
+	}
+
+	gtk_tree_model_get (model, &iter, ID_COLUMN, &theme, NAME_COLUMN, &name, -1);
+
+	if (theme == NULL)
+	{
+		g_free (name);
+		return;
+	}
+
+	preview_set_theme (preview, theme, name);
+	config_set_theme (theme);
+
+	g_free (theme);
+	g_free (name);
+}
+
+static void
+activate_delay_value_changed_cb (GtkRange *range,
+                                 gpointer  user_data)
+{
+	gdouble value;
+
+	value = gtk_range_get_value (range);
+	config_set_activate_delay ((gint32)value);
+}
+
+static int
+compare_theme_names (char *name_a,
+                     char *name_b,
+                     char *id_a,
+                     char *id_b)
+{
+
+	if (id_a == NULL)
+	{
+		return 1;
+	}
+	else if (id_b == NULL)
+	{
+		return -1;
+	}
+
+	if (strcmp (id_a, "__blank-only") == 0)
+	{
+		return -1;
+	}
+	else if (strcmp (id_b, "__blank-only") == 0)
+	{
+		return 1;
+	}
+	else if (strcmp (id_a, "__random") == 0)
+	{
+		return -1;
+	}
+	else if (strcmp (id_b, "__random") == 0)
+	{
+		return 1;
+	}
+	else if (strcmp (id_a, "__separator") == 0)
+	{
+		return -1;
+	}
+	else if (strcmp (id_b, "__separator") == 0)
+	{
+		return 1;
+	}
+
+	if (name_a == NULL)
+	{
+		return 1;
+	}
+	else if (name_b == NULL)
+	{
+		return -1;
+	}
+
+	return g_utf8_collate (name_a, name_b);
+}
+
+static int
+compare_theme  (GtkTreeModel *model,
+                GtkTreeIter  *a,
+                GtkTreeIter  *b,
+                gpointer      user_data)
+{
+	char *name_a;
+	char *name_b;
+	char *id_a;
+	char *id_b;
+	int   result;
+
+	gtk_tree_model_get (model, a, NAME_COLUMN, &name_a, -1);
+	gtk_tree_model_get (model, b, NAME_COLUMN, &name_b, -1);
+	gtk_tree_model_get (model, a, ID_COLUMN, &id_a, -1);
+	gtk_tree_model_get (model, b, ID_COLUMN, &id_b, -1);
+
+	result = compare_theme_names (name_a, name_b, id_a, id_b);
+
+	g_free (name_a);
+	g_free (name_b);
+	g_free (id_a);
+	g_free (id_b);
+
+	return result;
+}
+
+static gboolean
+separator_func (GtkTreeModel *model,
+                GtkTreeIter  *iter,
+                gpointer      data)
+{
+	int       column = GPOINTER_TO_INT (data);
+	gboolean  res = FALSE;
+	char     *text;
+
+	gtk_tree_model_get (model, iter, column, &text, -1);
+
+	if (text != NULL && strcmp (text, "__separator") == 0)
+	{
+		res = TRUE;
+	}
+
+	g_free (text);
+
+	return res;
+}
+
+static void
+setup_treeview (GtkWidget *tree,
+                GtkWidget *preview)
+{
+	GtkTreeStore      *store;
+	GtkTreeViewColumn *column;
+	GtkCellRenderer   *renderer;
+	GtkTreeSelection  *select;
+
+	store = gtk_tree_store_new (N_COLUMNS,
+	                            G_TYPE_STRING,
+	                            G_TYPE_STRING);
+	populate_model (store);
+
+	gtk_tree_view_set_model (GTK_TREE_VIEW (tree),
+	                         GTK_TREE_MODEL (store));
+
+	g_object_unref (store);
+
+	g_object_set (tree, "show-expanders", FALSE, NULL);
+
+	renderer = gtk_cell_renderer_text_new ();
+	column = gtk_tree_view_column_new_with_attributes ("Name", renderer,
+	         "text", NAME_COLUMN,
+	         NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+	gtk_tree_view_column_set_sort_column_id (column, NAME_COLUMN);
+	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store),
+	                                 NAME_COLUMN,
+	                                 compare_theme,
+	                                 NULL, NULL);
+	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
+	                                      NAME_COLUMN,
+	                                      GTK_SORT_ASCENDING);
+
+	gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (tree),
+	                                      separator_func,
+	                                      GINT_TO_POINTER (ID_COLUMN),
+	                                      NULL);
+
+	select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
+	gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
+	g_signal_connect (select, "changed",
+	                  G_CALLBACK (tree_selection_changed_cb),
+	                  preview);
+
+}
+
+static void
+setup_treeview_selection (GtkWidget *tree)
+{
+	char         *theme;
+	GtkTreeModel *model;
+	GtkTreeIter   iter;
+	GtkTreePath  *path = NULL;
+	gboolean      is_writable;
+
+	theme = config_get_theme (&is_writable);
+
+	if (! is_writable)
+	{
+		gtk_widget_set_sensitive (tree, FALSE);
+	}
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
+
+	if (theme && gtk_tree_model_get_iter_first (model, &iter))
+	{
+
+		do
+		{
+			char *id;
+			gboolean found;
+
+			gtk_tree_model_get (model, &iter,
+			                    ID_COLUMN, &id, -1);
+			found = (id && strcmp (id, theme) == 0);
+			g_free (id);
+
+			if (found)
+			{
+				path = gtk_tree_model_get_path (model, &iter);
+				break;
+			}
+
+		}
+		while (gtk_tree_model_iter_next (model, &iter));
+	}
+
+	if (path)
+	{
+		gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree),
+		                          path,
+		                          NULL,
+		                          FALSE);
+
+		gtk_tree_path_free (path);
+	}
+
+	g_free (theme);
+}
+
+static void
+reload_themes (void)
+{
+	GtkWidget    *treeview;
+	GtkTreeModel *model;
+
+	treeview = GTK_WIDGET (gtk_builder_get_object (builder, "savers_treeview"));
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
+	gtk_tree_store_clear (GTK_TREE_STORE (model));
+	populate_model (GTK_TREE_STORE (model));
+
+	gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
+	                         GTK_TREE_MODEL (model));
+}
+
+static void
+theme_copy_complete_cb (GtkWidget *dialog, gpointer user_data)
+{
+	reload_themes ();
+	gtk_widget_destroy (dialog);
+}
+
+static void
+theme_installer_run (GtkWidget *prefs_dialog, GList *files)
+{
+	GtkWidget *copy_dialog;
+
+	copy_dialog = copy_theme_dialog_new (files);
+	g_list_free_full (files, g_object_unref);
+
+	gtk_window_set_transient_for (GTK_WINDOW (copy_dialog),
+	                              GTK_WINDOW (prefs_dialog));
+	gtk_window_set_icon_name (GTK_WINDOW (copy_dialog),
+	                          "preferences-desktop-screensaver");
+
+	g_signal_connect (copy_dialog, "complete",
+	                  G_CALLBACK (theme_copy_complete_cb), NULL);
+
+	copy_theme_dialog_begin (COPY_THEME_DIALOG (copy_dialog));
+}
+
+/* Callback issued during drag movements */
+static gboolean
+drag_motion_cb (GtkWidget      *widget,
+                GdkDragContext *context,
+                int             x,
+                int             y,
+                guint           time,
+                gpointer        data)
+{
+	return FALSE;
+}
+
+/* Callback issued during drag leaves */
+static void
+drag_leave_cb (GtkWidget      *widget,
+               GdkDragContext *context,
+               guint           time,
+               gpointer        data)
+{
+	gtk_widget_queue_draw (widget);
+}
+
+/* GIO has no version of mate_vfs_uri_list_parse(), so copy from MateVFS
+ * and re-work to create GFiles.
+**/
+static GList *
+uri_list_parse (const gchar *uri_list)
+{
+	const gchar *p, *q;
+	gchar *retval;
+	GFile *file;
+	GList *result = NULL;
+
+	g_return_val_if_fail (uri_list != NULL, NULL);
+
+	p = uri_list;
+
+	/* We don't actually try to validate the URI according to RFC
+	 * 2396, or even check for allowed characters - we just ignore
+	 * comments and trim whitespace off the ends.  We also
+	 * allow LF delimination as well as the specified CRLF.
+	 */
+	while (p != NULL)
+	{
+		if (*p != '#')
+		{
+			while (g_ascii_isspace (*p))
+				p++;
+
+			q = p;
+			while ((*q != '\0')
+			        && (*q != '\n')
+			        && (*q != '\r'))
+				q++;
+
+			if (q > p)
+			{
+				q--;
+				while (q > p
+				        && g_ascii_isspace (*q))
+					q--;
+
+				retval = g_malloc (q - p + 2);
+				strncpy (retval, p, q - p + 1);
+				retval[q - p + 1] = '\0';
+
+				file = g_file_new_for_uri (retval);
+
+				g_free (retval);
+
+				if (file != NULL)
+					result = g_list_prepend (result, file);
+			}
+		}
+		p = strchr (p, '\n');
+		if (p != NULL)
+			p++;
+	}
+
+	return g_list_reverse (result);
+}
+
+/* Callback issued on actual drops. Attempts to load the file dropped. */
+static void
+drag_data_received_cb (GtkWidget        *widget,
+                       GdkDragContext   *context,
+                       int               x,
+                       int               y,
+                       GtkSelectionData *selection_data,
+                       guint             info,
+                       guint             time,
+                       gpointer          data)
+{
+	GList     *files;
+
+	if (!(info == TARGET_URI_LIST || info == TARGET_NS_URL))
+		return;
+
+	files = uri_list_parse ((char *) gtk_selection_data_get_data (selection_data));
+	if (files != NULL)
+	{
+		GtkWidget *prefs_dialog;
+
+		prefs_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "prefs_dialog"));
+		theme_installer_run (prefs_dialog, files);
+	}
+}
+
+/* Adapted from totem_time_to_string_text */
+static char *
+time_to_string_text (long time)
+{
+	char  *secs, *mins, *hours, *string;
+	char  *chk_hour_str, *chk_minute_str, *chk_hour_minute_str;
+	char  *chk_ascii_str;
+	int    sec, min, hour;
+	size_t chk_ascii_len;
+	int    len_minutes;
+	int    n, inc_len;
+	int    diff;
+
+	sec = time % 60;
+	time = time - sec;
+	min = (time % (60 * 60)) / 60;
+	time = time - (min * 60);
+	hour = time / (60 * 60);
+
+	hours = g_strdup_printf (ngettext ("%d hour",
+	                                   "%d hours", hour), hour);
+
+	mins = g_strdup_printf (ngettext ("%d minute",
+	                                  "%d minutes", min), min);
+
+	secs = g_strdup_printf (ngettext ("%d second",
+	                                  "%d seconds", sec), sec);
+
+	/* inc_len = it's the lenght of the string "1 hour 59 minutes" */
+	chk_hour_str = g_strdup_printf (ngettext ("%d hour",
+	                                          "%d hours", 1), 1);
+	chk_minute_str = g_strdup_printf (ngettext ("%d minute",
+	                                            "%d minutes", 59), 59);
+	chk_hour_minute_str = g_strdup_printf (_("%s %s"),
+	                                       chk_hour_str, chk_minute_str);
+	inc_len = strlen (chk_hour_minute_str) - 1;
+	g_free (chk_hour_str);
+	g_free (chk_minute_str);
+	g_free (chk_hour_minute_str);
+
+	len_minutes = 0;
+	for (n = 2; n < 60; n++)
+	{
+		char   *minute_str    = g_strdup_printf (ngettext ("%d minute",
+		                                                   "%d minutes", n), n);
+		char   *ascii_str     = g_str_to_ascii (minute_str, NULL);
+		size_t  ascii_str_len = strlen (ascii_str);
+		size_t  extra_length  = (n < 10) ? 2 : 3;
+
+		diff = (int) (ascii_str_len - extra_length);
+		if (diff > len_minutes)
+			len_minutes = diff;
+
+		g_free (minute_str);
+		g_free (ascii_str);
+	}
+
+	/* check the lenght of the string "1 minute" */
+	chk_minute_str = g_strdup_printf (ngettext ("%d minute",
+	                                            "%d minutes", 1), 1);
+	chk_ascii_str = g_str_to_ascii (chk_minute_str, NULL);
+	chk_ascii_len = strlen (chk_ascii_str);
+	diff = (int) (chk_ascii_len - 2);
+
+	if (diff > len_minutes)
+		len_minutes = diff;
+
+	g_free (chk_minute_str);
+	g_free (chk_ascii_str);
+
+	/* len_minutes = MAX (1, len_minutes) */
+	if (len_minutes < 1)
+		len_minutes = 1;
+
+	if (hour > 0)
+	{
+		if (sec > 0)
+			/* hour:minutes:seconds */
+			string = g_strdup_printf (_("%s %s %s"), hours, mins, secs);
+		else if (min > 0)
+			/* hour:minutes */
+			string = g_strdup_printf (_("%s %s"), hours, mins);
+		else
+			/* hour */
+			string = g_strdup_printf (_("%s"), hours);
+	}
+	else if (min > 0)
+	{
+		if (sec > 0)
+		{
+			/* minutes:seconds */
+			string = g_strdup_printf (_("%s %s"), mins, secs);
+		}
+		else
+		{
+			/* minutes */
+			size_t max_len;
+
+			string = g_strdup_printf (_("%s"), mins);
+
+			if (min == 1)
+				max_len = (size_t) (len_minutes + inc_len + 3);
+			else if (min < 10)
+				max_len = (size_t) (len_minutes + inc_len);
+			else
+				max_len = (size_t) (len_minutes + inc_len - 1);
+
+			while (strlen (string) != max_len)
+			{
+				char *string_aux;
+
+				if (strlen (string) % 2 == 0)
+					string_aux = g_strconcat (string, " ", NULL);
+				else
+					string_aux = g_strconcat (" " , string, NULL);
+
+				g_free (string);
+				string = string_aux;
+			}
+		}
+	}
+	else
+	{
+		/* seconds */
+		string = g_strdup_printf (_("%s"), secs);
+	}
+
+	g_free (hours);
+	g_free (mins);
+	g_free (secs);
+
+	return string;
+}
+
+static char *
+format_value_callback_time (GtkScale *scale,
+                            gdouble   value)
+{
+	if (value == 0)
+		return g_strdup_printf (_("Never"));
+
+	return time_to_string_text ((long) (value * 60.0));
+}
+
+static void
+lock_checkbox_toggled (GtkToggleButton *button, gpointer user_data)
+{
+	config_set_lock (gtk_toggle_button_get_active (button));
+}
+
+static void
+enabled_checkbox_toggled (GtkToggleButton *button, gpointer user_data)
+{
+	config_set_enabled (gtk_toggle_button_get_active (button));
+}
+
+static void
+picture_filename_changed (GtkFileChooserButton *button, gpointer user_data)
+{
+	char *picture_filename;
+
+	picture_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (button));
+	g_settings_set_string (screensaver_settings, "picture-filename", picture_filename);
+	g_free (picture_filename);
+}
+
+static void
+ui_disable_lock (gboolean disable)
+{
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "lock_checkbox"));
+	gtk_widget_set_sensitive (widget, !disable);
+	if (disable)
+	{
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+	}
+}
+
+static void
+ui_set_lock (gboolean enabled)
+{
+	GtkWidget *widget;
+	gboolean   active;
+	gboolean   lock_disabled;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "lock_checkbox"));
+
+	active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+	if (active != enabled)
+	{
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), enabled);
+	}
+	lock_disabled = config_get_lock_disabled ();
+	ui_disable_lock (lock_disabled);
+}
+
+static void
+ui_set_enabled (gboolean enabled)
+{
+	GtkWidget *widget;
+	gboolean   active;
+	gboolean   is_writable;
+	gboolean   lock_disabled;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "enable_checkbox"));
+	active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+	if (active != enabled)
+	{
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), enabled);
+	}
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "lock_checkbox"));
+	config_get_lock (&is_writable);
+	if (is_writable)
+	{
+		gtk_widget_set_sensitive (widget, enabled);
+	}
+	lock_disabled = config_get_lock_disabled ();
+	ui_disable_lock(lock_disabled);
+}
+
+static void
+ui_set_delay (gdouble delay)
+{
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "activate_delay_hscale"));
+	gtk_range_set_value (GTK_RANGE (widget), delay);
+}
+
+static void
+key_changed_cb (GSettings *settings, const gchar *key, gpointer data)
+{
+	if (strcmp (key, KEY_IDLE_ACTIVATION_ENABLED) == 0)
+	{
+			gboolean enabled;
+
+			enabled = g_settings_get_boolean (settings, key);
+
+			ui_set_enabled (enabled);
+	}
+	else if (strcmp (key, KEY_LOCK) == 0)
+	{
+		        gboolean enabled;
+
+			enabled = g_settings_get_boolean (settings, key);
+
+			ui_set_lock (enabled);
+	}
+	else if (strcmp (key, KEY_LOCK_DISABLE) == 0)
+	{
+		        gboolean disabled;
+
+			disabled = g_settings_get_boolean (settings, key);
+
+			ui_disable_lock (disabled);
+	}
+	else if (strcmp (key, KEY_THEMES) == 0)
+	{
+		        GtkWidget *treeview;
+
+			treeview = GTK_WIDGET (gtk_builder_get_object (builder, "savers_treeview"));
+			setup_treeview_selection (treeview);
+	}
+	else if (strcmp (key, KEY_IDLE_DELAY) == 0)
+	{
+			int delay;
+
+			delay = g_settings_get_int (settings, key);
+			ui_set_delay ((gdouble) delay);
+
+	}
+	else
+	{
+		/*g_warning ("Config key not handled: %s", key);*/
+	}
+}
+
+static void
+fullscreen_preview_previous_cb (GtkWidget *fullscreen_preview_window,
+                                gpointer   user_data)
+{
+	GtkWidget        *treeview;
+	GtkTreeSelection *selection;
+
+	treeview = GTK_WIDGET (gtk_builder_get_object (builder, "savers_treeview"));
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+	tree_selection_previous (selection);
+}
+
+static void
+fullscreen_preview_next_cb (GtkWidget *fullscreen_preview_window,
+                            gpointer   user_data)
+{
+	GtkWidget        *treeview;
+	GtkTreeSelection *selection;
+
+	treeview = GTK_WIDGET (gtk_builder_get_object (builder, "savers_treeview"));
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+	tree_selection_next (selection);
+}
+
+static void
+fullscreen_preview_cancelled_cb (GtkWidget *button,
+                                 gpointer   user_data)
+{
+
+	GtkWidget *fullscreen_preview_area;
+	GtkWidget *fullscreen_preview_window;
+	GtkWidget *preview_area;
+	GtkWidget *dialog;
+
+	preview_area = GTK_WIDGET (gtk_builder_get_object (builder, "preview_area"));
+	gs_job_set_widget (job, preview_area);
+
+	fullscreen_preview_area = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_area"));
+	gtk_widget_queue_draw (fullscreen_preview_area);
+
+	fullscreen_preview_window = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_window"));
+	gtk_widget_hide (fullscreen_preview_window);
+
+	dialog = GTK_WIDGET (gtk_builder_get_object (builder, "prefs_dialog"));
+	gtk_widget_show (dialog);
+	gtk_window_present (GTK_WINDOW (dialog));
+}
+
+static void
+fullscreen_preview_start_cb (GtkWidget *widget,
+                             gpointer   user_data)
+{
+	GtkWidget *fullscreen_preview_area;
+	GtkWidget *fullscreen_preview_window;
+	GtkWidget *dialog;
+
+	dialog = GTK_WIDGET (gtk_builder_get_object (builder, "prefs_dialog"));
+	gtk_widget_hide (dialog);
+
+	fullscreen_preview_window = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_window"));
+
+	gtk_window_fullscreen (GTK_WINDOW (fullscreen_preview_window));
+	gtk_window_set_keep_above (GTK_WINDOW (fullscreen_preview_window), TRUE);
+
+	gtk_widget_show (fullscreen_preview_window);
+	gtk_widget_grab_focus (fullscreen_preview_window);
+
+	fullscreen_preview_area = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_area"));
+	gtk_widget_queue_draw (fullscreen_preview_area);
+	gs_job_set_widget (job, fullscreen_preview_area);
+}
+
+static void
+constrain_list_size (GtkWidget      *widget,
+                     GtkAllocation  *allocation,
+                     GtkWidget      *to_size)
+{
+	GtkRequisition req;
+	int            max_height;
+
+	/* constrain height to be the tree height up to a max */
+	max_height = (HeightOfScreen (gdk_x11_screen_get_xscreen (gtk_widget_get_screen (widget)))) / 4;
+
+	gtk_widget_get_preferred_size (to_size, &req, NULL);
+	allocation->height = MIN (req.height, max_height);
+}
+
+static void
+setup_list_size_constraint (GtkWidget *widget,
+                            GtkWidget *to_size)
+{
+	g_signal_connect (widget, "size-allocate",
+	                  G_CALLBACK (constrain_list_size), to_size);
+}
+
+static gboolean
+check_is_root_user (void)
+{
+#ifndef G_OS_WIN32
+	uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
+	gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
+
+#ifdef HAVE_GETRESUID
+	if (getresuid (&ruid, &euid, &suid) != 0 ||
+	        getresgid (&rgid, &egid, &sgid) != 0)
+#endif /* HAVE_GETRESUID */
+	{
+		suid = ruid = getuid ();<--- Variable 'suid' is assigned a value that is never used.
+		sgid = rgid = getgid ();<--- Variable 'sgid' is assigned a value that is never used.
+		euid = geteuid ();<--- Variable 'euid' is assigned a value that is never used.
+		egid = getegid ();<--- Variable 'egid' is assigned a value that is never used.
+	}
+
+	if (ruid == 0)
+	{
+		return TRUE;
+	}
+
+#endif
+	return FALSE;
+}
+
+static void
+setup_for_root_user (void)
+{
+	GtkWidget *lock_checkbox;
+	GtkWidget *label;
+
+	lock_checkbox = GTK_WIDGET (gtk_builder_get_object (builder, "lock_checkbox"));
+	label = GTK_WIDGET (gtk_builder_get_object (builder, "root_warning_label"));
+
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lock_checkbox), FALSE);
+	gtk_widget_set_sensitive (lock_checkbox, FALSE);
+
+	gtk_widget_show (label);
+}
+
+/* copied from gs-window-x11.c */
+#ifndef _GNU_SOURCE
+extern char **environ;
+#endif
+
+static gchar **
+spawn_make_environment_for_display (GdkDisplay *display,
+                                    gchar     **envp)
+{
+	gchar **retval = NULL;
+	const gchar *display_name;
+	gint    display_index = -1;
+	gint    i, env_len;
+
+	g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+	if (envp == NULL)
+		envp = environ;
+
+	for (env_len = 0; envp[env_len]; env_len++)
+		if (strncmp (envp[env_len], "DISPLAY", strlen ("DISPLAY")) == 0)
+			display_index = env_len;
+
+	retval = g_new (char *, env_len + 1);
+	retval[env_len] = NULL;
+
+	display_name = gdk_display_get_name (display);
+
+	for (i = 0; i < env_len; i++)
+		if (i == display_index)
+			retval[i] = g_strconcat ("DISPLAY=", display_name, NULL);
+		else
+			retval[i] = g_strdup (envp[i]);
+
+	g_assert (i == env_len);
+
+	return retval;
+}
+
+static gboolean
+spawn_command_line_on_display_sync (GdkDisplay  *display,
+                                    const gchar  *command_line,
+                                    char        **standard_output,
+                                    char        **standard_error,
+                                    int          *exit_status,
+                                    GError      **error)
+{
+	char     **argv = NULL;
+	char     **envp = NULL;
+	gboolean   retval;
+
+	g_return_val_if_fail (command_line != NULL, FALSE);
+
+	if (! g_shell_parse_argv (command_line, NULL, &argv, error))
+	{
+		return FALSE;
+	}
+
+	envp = spawn_make_environment_for_display (display, NULL);
+
+	retval = g_spawn_sync (NULL,
+	                       argv,
+	                       envp,
+	                       G_SPAWN_SEARCH_PATH,
+	                       NULL,
+	                       NULL,
+	                       standard_output,
+	                       standard_error,
+	                       exit_status,
+	                       error);
+
+	g_strfreev (argv);
+	g_strfreev (envp);
+
+	return retval;
+}
+
+static GdkVisual *
+get_best_visual_for_display (GdkDisplay *display)
+{
+	GdkScreen    *screen;
+	char         *std_output;
+	int           exit_status;
+	GError       *error;
+	unsigned long v;
+	char          c;
+	GdkVisual    *visual;
+	gboolean      res;
+
+	visual = NULL;
+	screen = gdk_display_get_default_screen (display);
+
+	error = NULL;
+	std_output = NULL;
+	res = spawn_command_line_on_display_sync (display,
+	        MATE_SCREENSAVER_GL_HELPER_PATH,
+	        &std_output,
+	        NULL,
+	        &exit_status,
+	        &error);
+	if (! res)
+	{
+		gs_debug ("Could not run command '%s': %s",
+		          MATE_SCREENSAVER_GL_HELPER_PATH, error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	if (1 == sscanf (std_output, "0x%lx %c", &v, &c))
+	{
+		if (v != 0)
+		{
+			VisualID      visual_id;
+
+			visual_id = (VisualID) v;
+			visual = gdk_x11_screen_lookup_visual (screen, visual_id);
+
+			gs_debug ("Found best GL visual for display %s: 0x%x",
+			          gdk_display_get_name (display),
+			          (unsigned int) visual_id);
+		}
+	}
+out:
+	g_free (std_output);
+
+	return visual;
+}
+
+static void
+widget_set_best_visual (GtkWidget *widget)
+{
+	GdkVisual *visual;
+
+	g_return_if_fail (widget != NULL);
+
+	visual = get_best_visual_for_display (gtk_widget_get_display (widget));
+	if (visual != NULL)
+	{
+		gtk_widget_set_visual (widget, visual);
+		g_object_unref (visual);
+	}
+}
+
+static gboolean
+setup_treeview_idle (gpointer data)
+{
+	(void)data;			/* remove warning unused parameter ‘data’ */
+	GtkWidget *preview;
+	GtkWidget *treeview;
+
+	preview  = GTK_WIDGET (gtk_builder_get_object (builder, "preview_area"));
+	treeview = GTK_WIDGET (gtk_builder_get_object (builder, "savers_treeview"));
+
+	setup_treeview (treeview, preview);
+	setup_treeview_selection (treeview);
+
+	return FALSE;
+}
+
+static gboolean
+is_program_in_path (const char *program)
+{
+	char *tmp = g_find_program_in_path (program);
+	if (tmp != NULL)
+	{
+		g_free (tmp);
+		return TRUE;
+	}
+	else
+	{
+		return FALSE;
+	}
+}
+
+static void
+update_picture_filename_preview (GtkFileChooser *file_chooser,
+                                 gpointer        data)
+{
+	GtkWidget *preview;
+	char *uri;
+	gboolean have_preview = FALSE;
+
+	preview = GTK_WIDGET (data);
+	uri = gtk_file_chooser_get_preview_uri (file_chooser);
+	if (uri) {
+		GFile     *file;
+		GFileInfo *file_info;
+		time_t     mtime;
+		guint64    mtime_aux;
+		char      *thumb_path;
+
+		file = g_file_new_for_uri (uri);
+		file_info = g_file_query_info (file,
+		                               G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE","G_FILE_ATTRIBUTE_TIME_MODIFIED,
+		                               G_FILE_QUERY_INFO_NONE,
+		                               NULL, NULL);
+		g_object_unref (file);
+
+		if (file_info == NULL)
+			goto no_file_info;
+
+		mtime_aux = g_file_info_get_attribute_uint64 (file_info,
+		                                              G_FILE_ATTRIBUTE_TIME_MODIFIED);
+		mtime = (time_t)mtime_aux;
+		if ((thumb_path = mate_desktop_thumbnail_factory_lookup (thumb_factory, uri, mtime)) != NULL) {
+			/* try to load thumbnail from cache */
+			gtk_image_set_from_file (GTK_IMAGE (preview), thumb_path);
+			have_preview = TRUE;
+			g_free (thumb_path);
+		} else {
+			/* try to generate thumbnail from wallpaper & store to cache */
+			const char *content_type = g_file_info_get_content_type (file_info);
+			if (content_type != NULL) {
+				char *mime_type = g_content_type_get_mime_type (content_type);
+				if (mime_type != NULL) {
+					/* can generate thumbnail and did not fail previously */
+					if (mate_desktop_thumbnail_factory_can_thumbnail (thumb_factory, uri, mime_type, mtime)) {
+						GdkPixbuf *pixbuf;
+						pixbuf =  mate_desktop_thumbnail_factory_generate_thumbnail (thumb_factory,
+				                                                                             uri, mime_type);
+						if (pixbuf != NULL) {
+							gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
+							mate_desktop_thumbnail_factory_save_thumbnail (thumb_factory,
+							                                               pixbuf, uri, mtime);
+							have_preview = TRUE;
+							g_object_unref (pixbuf);
+						} else {
+							mate_desktop_thumbnail_factory_create_failed_thumbnail (thumb_factory,
+							                                                        uri, mtime);
+						}
+					}
+					g_free (mime_type);
+				}
+			}
+		}
+		g_object_unref (file_info);
+
+no_file_info:
+		g_free (uri);
+	}
+	gtk_file_chooser_set_preview_widget_active (file_chooser, have_preview);
+}
+
+static void
+init_capplet (void)
+{
+	GtkWidget *dialog;
+	GtkWidget *preview;
+	GtkWidget *treeview;
+	GtkWidget *list_scroller;
+	GtkWidget *activate_delay_hscale;
+	GtkWidget *activate_delay_hbox;
+	GtkWidget *label;
+	GtkWidget *enabled_checkbox;
+	GtkWidget *lock_checkbox;
+	GtkWidget *root_warning_label;
+	GtkWidget *preview_button;
+	GtkWidget *gpm_button;
+	GtkWidget *fullscreen_preview_window;
+	GtkWidget *fullscreen_preview_area;
+	GtkWidget *fullscreen_preview_previous;
+	GtkWidget *fullscreen_preview_next;
+	GtkWidget *fullscreen_preview_close;
+	GtkWidget *picture_filename;
+	GtkWidget *picture_filename_preview;
+	gdouble    activate_delay;
+	gboolean   enabled;
+	gboolean   is_writable;
+	GError    *error=NULL;
+	gint       mode;
+
+	builder = gtk_builder_new();
+	if (!gtk_builder_add_from_resource (builder, "/org/mate/screensaver/preferences.ui", &error))
+	{
+		g_warning("Couldn't load builder resource: %s", error->message);
+		g_error_free(error);
+	}
+
+	if (builder == NULL)
+	{
+
+		dialog = gtk_message_dialog_new (NULL,
+		                                 0, GTK_MESSAGE_ERROR,
+		                                 GTK_BUTTONS_OK,
+		                                 _("Could not load the main interface"));
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+		        _("Please make sure that the screensaver is properly installed"));
+
+		gtk_dialog_set_default_response (GTK_DIALOG (dialog),
+		                                 GTK_RESPONSE_OK);
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+		exit (1);
+	}
+
+	preview            = GTK_WIDGET (gtk_builder_get_object (builder, "preview_area"));
+	dialog             = GTK_WIDGET (gtk_builder_get_object (builder, "prefs_dialog"));
+	treeview           = GTK_WIDGET (gtk_builder_get_object (builder, "savers_treeview"));
+	list_scroller      = GTK_WIDGET (gtk_builder_get_object (builder, "themes_scrolled_window"));
+	activate_delay_hscale = GTK_WIDGET (gtk_builder_get_object (builder, "activate_delay_hscale"));
+	activate_delay_hbox   = GTK_WIDGET (gtk_builder_get_object (builder, "activate_delay_hbox"));
+	enabled_checkbox   = GTK_WIDGET (gtk_builder_get_object (builder, "enable_checkbox"));
+	lock_checkbox      = GTK_WIDGET (gtk_builder_get_object (builder, "lock_checkbox"));
+	root_warning_label = GTK_WIDGET (gtk_builder_get_object (builder, "root_warning_label"));
+	preview_button     = GTK_WIDGET (gtk_builder_get_object (builder, "preview_button"));
+	gpm_button         = GTK_WIDGET (gtk_builder_get_object (builder, "gpm_button"));
+	fullscreen_preview_window = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_window"));
+	fullscreen_preview_area = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_area"));
+	fullscreen_preview_close = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_close"));
+	fullscreen_preview_previous = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_previous_button"));
+	fullscreen_preview_next = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_next_button"));
+	picture_filename = GTK_WIDGET (gtk_builder_get_object (builder, "picture_filename"));
+
+	label              = GTK_WIDGET (gtk_builder_get_object (builder, "activate_delay_label"));
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), activate_delay_hscale);
+	label              = GTK_WIDGET (gtk_builder_get_object (builder, "savers_label"));
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), treeview);
+
+	gtk_widget_set_no_show_all (root_warning_label, TRUE);
+	widget_set_best_visual (preview);
+
+	if (! is_program_in_path (GPM_COMMAND))
+	{
+		gtk_widget_set_no_show_all (gpm_button, TRUE);
+		gtk_widget_hide (gpm_button);
+	}
+
+	screensaver_settings = g_settings_new (GSETTINGS_SCHEMA);
+	g_signal_connect (screensaver_settings,
+	                  "changed",
+	                  G_CALLBACK (key_changed_cb),
+	                  NULL);
+
+	session_settings = g_settings_new (SESSION_SETTINGS_SCHEMA);
+	g_signal_connect (session_settings,
+	                  "changed::" KEY_IDLE_DELAY,
+	                  G_CALLBACK (key_changed_cb),
+	                  NULL);
+
+	lockdown_settings = g_settings_new (LOCKDOWN_SETTINGS_SCHEMA);
+	g_signal_connect (lockdown_settings,
+	                  "changed::" KEY_LOCK_DISABLE,
+	                  G_CALLBACK (key_changed_cb),
+	                  NULL);
+
+	activate_delay = config_get_activate_delay (&is_writable);
+	ui_set_delay (activate_delay);
+	if (! is_writable)
+	{
+		gtk_widget_set_sensitive (activate_delay_hbox, FALSE);
+	}
+	g_signal_connect (activate_delay_hscale, "format-value",
+	                  G_CALLBACK (format_value_callback_time), NULL);
+
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lock_checkbox), config_get_lock (&is_writable));
+	if (! is_writable)
+	{
+		gtk_widget_set_sensitive (lock_checkbox, FALSE);
+	}
+	g_signal_connect (lock_checkbox, "toggled",
+	                  G_CALLBACK (lock_checkbox_toggled), NULL);
+
+	char *path = g_settings_get_string (screensaver_settings, "picture-filename");
+	gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (picture_filename), path);
+	g_free (path);
+	gtk_file_filter_add_pixbuf_formats (GTK_FILE_FILTER (gtk_builder_get_object (builder, "picture_filefilter")));
+	picture_filename_preview = gtk_image_new ();
+	gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (picture_filename), picture_filename_preview);
+	thumb_factory = mate_desktop_thumbnail_factory_new (MATE_DESKTOP_THUMBNAIL_SIZE_LARGE);
+	g_signal_connect (picture_filename, "update-preview",
+	                  G_CALLBACK (update_picture_filename_preview), picture_filename_preview);
+	g_signal_connect (picture_filename, "selection-changed",
+	                  G_CALLBACK (picture_filename_changed), NULL);
+
+	enabled = config_get_enabled (&is_writable);
+	ui_set_enabled (enabled);
+	if (! is_writable)
+	{
+		gtk_widget_set_sensitive (enabled_checkbox, FALSE);
+	}
+	g_signal_connect (enabled_checkbox, "toggled",
+	                  G_CALLBACK (enabled_checkbox_toggled), NULL);
+
+	setup_list_size_constraint (list_scroller, treeview);
+	gtk_widget_set_size_request (preview, 480, 300);
+	gtk_window_set_icon_name (GTK_WINDOW (dialog), "preferences-desktop-screensaver");
+	gtk_window_set_icon_name (GTK_WINDOW (fullscreen_preview_window), "screensaver");
+
+	g_signal_connect (fullscreen_preview_area,
+	                  "draw", G_CALLBACK (preview_on_draw),
+	                  NULL);
+
+	gtk_drag_dest_set (dialog, GTK_DEST_DEFAULT_ALL,
+	                   drop_types, G_N_ELEMENTS (drop_types),
+	                   GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE);
+
+	g_signal_connect (dialog, "drag-motion",
+	                  G_CALLBACK (drag_motion_cb), NULL);
+	g_signal_connect (dialog, "drag-leave",
+	                  G_CALLBACK (drag_leave_cb), NULL);
+	g_signal_connect (dialog, "drag-data-received",
+	                  G_CALLBACK (drag_data_received_cb), NULL);
+
+	gtk_widget_show_all (dialog);
+
+	/* Update list of themes if using random screensaver */
+	mode = g_settings_get_enum (screensaver_settings, KEY_MODE);
+	if (mode == GS_MODE_RANDOM) {
+		gchar **list;
+		list = get_all_theme_ids ();
+		g_settings_set_strv (screensaver_settings, KEY_THEMES, (const gchar * const*) list);
+		g_strfreev (list);
+	}
+
+	g_signal_connect (preview, "draw", G_CALLBACK (preview_on_draw), NULL);
+	gs_job_set_widget (job, preview);
+
+	if (check_is_root_user ())
+	{
+		setup_for_root_user ();
+	}
+
+	g_signal_connect (activate_delay_hscale, "value-changed",
+	                  G_CALLBACK (activate_delay_value_changed_cb), NULL);
+
+	g_signal_connect (dialog, "response",
+	                  G_CALLBACK (response_cb), NULL);
+
+	g_signal_connect (preview_button, "clicked",
+	                  G_CALLBACK (fullscreen_preview_start_cb),
+	                  treeview);
+
+	g_signal_connect (fullscreen_preview_close, "clicked",
+	                  G_CALLBACK (fullscreen_preview_cancelled_cb), NULL);
+	g_signal_connect (fullscreen_preview_previous, "clicked",
+	                  G_CALLBACK (fullscreen_preview_previous_cb), NULL);
+	g_signal_connect (fullscreen_preview_next, "clicked",
+	                  G_CALLBACK (fullscreen_preview_next_cb), NULL);
+
+	g_idle_add (setup_treeview_idle, NULL);
+}
+
+static void
+finalize_capplet (void)
+{
+	g_object_unref (screensaver_settings);
+	g_object_unref (session_settings);
+	g_object_unref (lockdown_settings);
+	g_object_unref (thumb_factory);
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+
+#ifdef ENABLE_NLS
+	bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
+# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+# endif
+	textdomain (GETTEXT_PACKAGE);
+#endif
+
+	gtk_init (&argc, &argv);
+
+	job = gs_job_new ();
+	theme_manager = gs_theme_manager_new ();
+
+	init_capplet ();
+
+	gtk_main ();
+
+	finalize_capplet ();
+
+	g_object_unref (theme_manager);
+	g_object_unref (job);
+
+	return 0;
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/2.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/2.html new file mode 100644 index 0000000..04dad1b --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/2.html @@ -0,0 +1,2651 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
/*
+ * Copyright (C) 2005 Ray Strode <rstrode@redhat.com>,
+ *                    Matthias Clasen <mclasen@redhat.com>,
+ *                    Søren Sandmann <sandmann@redhat.com>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * Originally written by: Ray Strode <rstrode@redhat.com>
+ *
+ * Later contributions by: Matthias Clasen <mclasen@redhat.com>
+ *                         Søren Sandmann <sandmann@redhat.com>
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <sysexits.h>
+#include <time.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include "gs-theme-window.h"
+
+#ifndef trunc
+#define trunc(x) (((x) > 0.0) ? floor((x)) : -floor(-(x)))
+#endif
+
+#ifndef OPTIMAL_FRAME_RATE
+#define OPTIMAL_FRAME_RATE (25.0)
+#endif
+
+#ifndef STAT_PRINT_FREQUENCY
+#define STAT_PRINT_FREQUENCY (2000)
+#endif
+
+#ifndef FLOATER_MAX_SIZE
+#define FLOATER_MAX_SIZE (128.0)
+#endif
+
+#ifndef FLOATER_MIN_SIZE
+#define FLOATER_MIN_SIZE (16.0)
+#endif
+#ifndef FLOATER_DEFAULT_COUNT
+#define FLOATER_DEFAULT_COUNT (5)
+#endif
+
+#ifndef SMALL_ANGLE
+#define SMALL_ANGLE (0.025 * G_PI)
+#endif
+
+#ifndef BIG_ANGLE
+#define BIG_ANGLE (0.125 * G_PI)
+#endif
+
+#ifndef GAMMA
+#define GAMMA 2.2
+#endif
+
+typedef struct _Point Point;
+typedef struct _Path Path;
+typedef struct _Rectangle Rectangle;
+typedef struct _ScreenSaverFloater ScreenSaverFloater;
+typedef struct _CachedSource CachedSource;
+typedef struct _ScreenSaver ScreenSaver;
+
+struct _Point
+{
+	gdouble x, y;
+};
+
+struct _Path
+{
+	Point start_point;
+	Point start_control_point;
+	Point end_control_point;
+	Point end_point;
+
+	gdouble x_linear_coefficient,
+	        y_linear_coefficient;
+
+	gdouble x_quadratic_coefficient,
+	        y_quadratic_coefficient;
+
+	gdouble x_cubic_coefficient,
+	        y_cubic_coefficient;
+
+	gdouble duration;
+};
+
+struct _CachedSource
+{
+	cairo_pattern_t *pattern;
+	gint width, height;
+};
+
+struct _Rectangle
+{
+	Point top_left_point;
+	Point bottom_right_point;
+};
+
+struct _ScreenSaverFloater
+{
+	GdkRectangle bounds;
+
+	Point start_position;
+	Point position;
+
+	gdouble scale;
+	gdouble opacity;
+
+	Path *path;
+	gdouble path_start_time;
+	gdouble path_start_scale;
+	gdouble path_end_scale;
+
+	gdouble angle;
+	gdouble angle_increment;
+};
+
+struct _ScreenSaver
+{
+	GtkWidget  *drawing_area;
+	Rectangle canvas_rectangle;
+	GHashTable *cached_sources;
+
+	char *filename;
+
+	gdouble first_update_time;
+
+	gdouble last_calculated_stats_time,
+	        current_calculated_stats_time;
+	gint update_count, frame_count;
+
+	gdouble updates_per_second;
+	gdouble frames_per_second;
+
+	guint state_update_timeout_id;
+	guint stats_update_timeout_id;
+
+	GList *floaters;
+	gint max_floater_count;
+
+	guint should_do_rotations: 1;
+	guint should_show_paths : 1;
+	guint draw_ops_pending : 1;
+};
+
+static Path *path_new (Point *start_point,
+                       Point *start_control_point,
+                       Point *end_control_point,
+                       Point *end_point,
+                       gdouble duration);
+static void path_free (Path *path);
+
+static ScreenSaverFloater *screen_saver_floater_new (ScreenSaver *screen_saver,
+        Point       *position,
+        gdouble      scale);
+static void screen_saver_floater_free (ScreenSaver        *screen_saver,
+                                       ScreenSaverFloater *floater);
+static gboolean screen_saver_floater_is_off_canvas (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater);
+static gboolean screen_saver_floater_should_bubble_up (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             performance_ratio,
+        gdouble            *duration);
+static gboolean screen_saver_floater_should_come_on_screen (ScreenSaver   *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             performance_ratio,
+        gdouble            *duration);
+static Point screen_saver_floater_get_position_from_time (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             time);
+static gdouble screen_saver_floater_get_scale_from_time (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             time);
+static gdouble screen_saver_floater_get_angle_from_time (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             time);
+
+static Path *screen_saver_floater_create_path_to_on_screen (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             duration);
+static Path *screen_saver_floater_create_path_to_bubble_up (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             duration);
+static Path *screen_saver_floater_create_path_to_random_point (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             duration);
+static Path *screen_saver_floater_create_path (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater);
+static void screen_saver_floater_update_state (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             time);
+
+static gboolean screen_saver_floater_do_draw (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        cairo_t            *context);
+
+static CachedSource *cached_source_new (cairo_pattern_t *pattern,
+                                        gint             width,
+                                        gint             height);
+static void cached_source_free (CachedSource *source);
+
+static ScreenSaver *screen_saver_new (GtkWidget       *drawing_area,
+                                      const gchar     *filename,
+                                      gint             max_floater_count,
+                                      gboolean         should_do_rotations,
+                                      gboolean         should_show_paths);
+static void screen_saver_free (ScreenSaver *screen_saver);
+static gdouble screen_saver_get_timestamp (ScreenSaver *screen_saver);
+static void screen_saver_get_initial_state (ScreenSaver *screen_saver);
+static void screen_saver_update_state (ScreenSaver *screen_saver,
+                                       gdouble      time);
+static gboolean screen_saver_do_update_state (ScreenSaver *screen_saver);
+static gboolean screen_saver_do_update_stats (ScreenSaver *screen_saver);
+static gdouble screen_saver_get_updates_per_second (ScreenSaver *screen_saver);
+static gdouble screen_saver_get_frames_per_second (ScreenSaver *screen_saver);
+static gdouble screen_saver_get_image_cache_usage (ScreenSaver *screen_saver);
+static void screen_saver_create_floaters (ScreenSaver *screen_saver);
+static void screen_saver_destroy_floaters (ScreenSaver *screen_saver);
+static void screen_saver_on_size_allocate (ScreenSaver   *screen_saver,
+        GtkAllocation *allocation);
+static void screen_saver_on_draw (ScreenSaver    *screen_saver,
+        cairo_t *context);
+static gboolean do_print_screen_saver_stats (ScreenSaver *screen_saver);
+static GdkPixbuf *gamma_correct (const GdkPixbuf *input_pixbuf);
+
+static CachedSource*
+cached_source_new (cairo_pattern_t *pattern,
+                   gint              width,
+                   gint             height)
+{
+	CachedSource *source;
+
+	source = g_new (CachedSource, 1);
+	source->pattern = cairo_pattern_reference (pattern);
+	source->width = width;
+	source->height = height;
+
+	return source;
+}
+
+static void
+cached_source_free (CachedSource *source)
+{
+	if (source == NULL)
+		return;
+
+	cairo_pattern_destroy (source->pattern);
+
+	g_free (source);
+}
+
+static Path *
+path_new (Point *start_point,
+          Point *start_control_point,
+          Point *end_control_point,
+          Point *end_point,
+          gdouble duration)
+{
+	Path *path;
+
+	path = g_new (Path, 1);
+	path->start_point = *start_point;
+	path->start_control_point = *start_control_point;
+	path->end_control_point = *end_control_point;
+	path->end_point = *end_point;
+	path->duration = duration;
+
+	/* we precompute the coefficients to the cubic bezier curve here
+	 * so that we don't have to do it repeatedly later The equation is:
+	 *
+	 * B(t) = A * t^3 + B * t^2 + C * t + start_point
+	 */
+	path->x_linear_coefficient = 3 * (start_control_point->x - start_point->x);
+	path->x_quadratic_coefficient = 3 * (end_control_point->x -
+	                                     start_control_point->x) -
+	                                path->x_linear_coefficient;
+	path->x_cubic_coefficient = end_point->x - start_point->x -
+	                            path->x_linear_coefficient -
+	                            path->x_quadratic_coefficient;
+
+	path->y_linear_coefficient = 3 * (start_control_point->y - start_point->y);
+	path->y_quadratic_coefficient = 3 * (end_control_point->y -
+	                                     start_control_point->y) -
+	                                path->y_linear_coefficient;
+	path->y_cubic_coefficient = end_point->y - start_point->y -
+	                            path->y_linear_coefficient -
+	                            path->y_quadratic_coefficient;
+	return path;
+}
+
+static void
+path_free (Path *path)
+{
+	g_free (path);
+}
+
+static ScreenSaverFloater*
+screen_saver_floater_new (ScreenSaver *screen_saver,
+                          Point       *position,<--- Parameter 'position' can be declared with const
+                          gdouble      scale)
+{
+	ScreenSaverFloater *floater;
+
+	floater = g_new (ScreenSaverFloater, 1);
+	floater->bounds.width = 0;
+	floater->start_position = *position;
+	floater->position = *position;
+	floater->scale = scale;
+	floater->opacity = pow (scale, 1.0 / GAMMA);
+	floater->path = NULL;
+	floater->path_start_time = 0.0;
+	floater->path_start_scale = 1.0;
+	floater->path_end_scale = 0.0;
+
+	floater->angle = 0.0;
+	floater->angle_increment = 0.0;
+
+	return floater;
+}
+
+void
+screen_saver_floater_free (ScreenSaver        *screen_saver,
+                           ScreenSaverFloater *floater)
+{
+	if (floater == NULL)
+		return;
+
+	path_free (floater->path);
+
+	g_free (floater);
+}
+
+static gboolean
+screen_saver_floater_is_off_canvas (ScreenSaver        *screen_saver,
+                                    ScreenSaverFloater *floater)
+{
+	if ((floater->position.x < screen_saver->canvas_rectangle.top_left_point.x) ||
+	        (floater->position.x > screen_saver->canvas_rectangle.bottom_right_point.x) ||
+	        (floater->position.y < screen_saver->canvas_rectangle.top_left_point.y) ||
+	        (floater->position.y > screen_saver->canvas_rectangle.bottom_right_point.y))
+		return TRUE;
+
+	return FALSE;
+}
+
+static gboolean
+screen_saver_floater_should_come_on_screen (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             performance_ratio,
+        gdouble            *duration)
+{
+
+	if (!screen_saver_floater_is_off_canvas (screen_saver, floater))
+		return FALSE;
+
+	if ((fabs (performance_ratio - .5) >= G_MINDOUBLE) &&
+	        (g_random_double () > .5))
+	{
+		if (duration)
+			*duration = g_random_double_range (3.0, 7.0);
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+screen_saver_floater_should_bubble_up (ScreenSaver        *screen_saver,
+                                       ScreenSaverFloater *floater,
+                                       gdouble             performance_ratio,
+                                       gdouble            *duration)
+{
+
+	if ((performance_ratio < .5) && (g_random_double () > .5))
+	{
+		if (duration)
+			*duration = performance_ratio * 30.0;
+
+		return TRUE;
+	}
+
+	if ((floater->scale < .3) && (g_random_double () > .6))
+	{
+		if (duration)
+			*duration = 30.0;
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static Point
+screen_saver_floater_get_position_from_time (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             time)
+{
+	Point point;
+
+	time = time / floater->path->duration;
+
+	point.x = floater->path->x_cubic_coefficient * (time * time * time) +
+	          floater->path->x_quadratic_coefficient * (time * time) +
+	          floater->path->x_linear_coefficient * (time) +
+	          floater->path->start_point.x;
+	point.y = floater->path->y_cubic_coefficient * (time * time * time) +
+	          floater->path->y_quadratic_coefficient * (time * time) +
+	          floater->path->y_linear_coefficient * (time) +
+	          floater->path->start_point.y;
+
+	return point;
+}
+
+static gdouble
+screen_saver_floater_get_scale_from_time (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             time)
+{
+	gdouble completion_ratio, total_scale_growth, new_scale;
+
+	completion_ratio = time / floater->path->duration;
+	total_scale_growth = (floater->path_end_scale - floater->path_start_scale);
+	new_scale = floater->path_start_scale + total_scale_growth * completion_ratio;
+
+	return CLAMP (new_scale, 0.0, 1.0);
+}
+
+static gdouble
+screen_saver_floater_get_angle_from_time (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             time)
+{
+	gdouble completion_ratio;
+	gdouble total_rotation;
+
+	completion_ratio = time / floater->path->duration;
+	total_rotation = floater->angle_increment * floater->path->duration;
+
+	return floater->angle + total_rotation * completion_ratio;
+}
+
+static Path *
+screen_saver_floater_create_path_to_on_screen (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             duration)
+{
+	Point start_position, end_position, start_control_point, end_control_point;
+	start_position = floater->position;
+
+	end_position.x = g_random_double_range (.25, .75) *
+	                 (screen_saver->canvas_rectangle.top_left_point.x +
+	                  screen_saver->canvas_rectangle.bottom_right_point.x);
+	end_position.y = g_random_double_range (.25, .75) *
+	                 (screen_saver->canvas_rectangle.top_left_point.y +
+	                  screen_saver->canvas_rectangle.bottom_right_point.y);
+
+	start_control_point.x = start_position.x + .9 * (end_position.x - start_position.x);
+	start_control_point.y = start_position.y + .9 * (end_position.y - start_position.y);
+
+	end_control_point.x = start_position.x + 1.0 * (end_position.x - start_position.x);
+	end_control_point.y = start_position.y + 1.0 * (end_position.y - start_position.y);
+
+	return path_new (&start_position, &start_control_point, &end_control_point,
+	                 &end_position, duration);
+}
+
+static Path *
+screen_saver_floater_create_path_to_bubble_up (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             duration)
+{
+	Point start_position, end_position, start_control_point, end_control_point;
+
+	start_position = floater->position;
+	end_position.x = start_position.x;
+	end_position.y = screen_saver->canvas_rectangle.top_left_point.y - FLOATER_MAX_SIZE;
+	start_control_point.x = .5 * start_position.x;
+	start_control_point.y = .5 * start_position.y;
+	end_control_point.x = 1.5 * end_position.x;
+	end_control_point.y = .5 * end_position.y;
+
+	return path_new (&start_position, &start_control_point, &end_control_point,
+	                 &end_position, duration);
+}
+
+static Path *
+screen_saver_floater_create_path_to_random_point (ScreenSaver        *screen_saver,
+        ScreenSaverFloater *floater,
+        gdouble             duration)
+{
+	Point start_position, end_position, start_control_point, end_control_point;
+
+	start_position = floater->position;
+
+	end_position.x = start_position.x +
+	                 (g_random_double_range (-.5, .5) * 4 * FLOATER_MAX_SIZE);
+	end_position.y = start_position.y +
+	                 (g_random_double_range (-.5, .5) * 4 * FLOATER_MAX_SIZE);
+
+	start_control_point.x = start_position.x + .95 * (end_position.x - start_position.x);
+	start_control_point.y = start_position.y + .95 * (end_position.y - start_position.y);
+
+	end_control_point.x = start_position.x + 1.0 * (end_position.x - start_position.x);
+	end_control_point.y = start_position.y + 1.0 * (end_position.y - start_position.y);
+
+	return path_new (&start_position, &start_control_point, &end_control_point,
+	                 &end_position, duration);
+}
+
+static Path *
+screen_saver_floater_create_path (ScreenSaver        *screen_saver,
+                                  ScreenSaverFloater *floater)
+{
+	gdouble performance_ratio;
+	gdouble duration;
+
+	performance_ratio =
+	    screen_saver_get_frames_per_second (screen_saver) / OPTIMAL_FRAME_RATE;
+
+	if (fabs (performance_ratio) <= G_MINDOUBLE)
+		performance_ratio = 1.0;
+
+	if (screen_saver_floater_should_bubble_up (screen_saver, floater, performance_ratio, &duration))
+		return screen_saver_floater_create_path_to_bubble_up (screen_saver, floater, duration);
+
+	if (screen_saver_floater_should_come_on_screen (screen_saver, floater, performance_ratio, &duration))
+		return screen_saver_floater_create_path_to_on_screen (screen_saver, floater, duration);
+
+	return screen_saver_floater_create_path_to_random_point (screen_saver, floater,
+	        g_random_double_range (3.0, 7.0));
+}
+
+static void
+screen_saver_floater_update_state (ScreenSaver        *screen_saver,
+                                   ScreenSaverFloater *floater,
+                                   gdouble             time)
+{
+	gdouble performance_ratio;
+
+	performance_ratio =
+	    screen_saver_get_frames_per_second (screen_saver) / OPTIMAL_FRAME_RATE;
+
+	if (floater->path == NULL)
+	{
+		floater->path = screen_saver_floater_create_path (screen_saver, floater);
+		floater->path_start_time = time;
+
+		floater->path_start_scale = floater->scale;
+
+		if (g_random_double () > .5)
+			floater->path_end_scale = g_random_double_range (0.10, performance_ratio);
+
+		/* poor man's distribution */
+		if (screen_saver->should_do_rotations &&
+		        (g_random_double () < .75 * performance_ratio))
+		{
+			gint r;
+
+			r = g_random_int_range (0, 100);
+			if (r < 80)
+				floater->angle_increment = 0.0;
+			else if (r < 95)
+				floater->angle_increment = g_random_double_range (-SMALL_ANGLE, SMALL_ANGLE);
+			else
+				floater->angle_increment = g_random_double_range (-BIG_ANGLE, BIG_ANGLE);
+		}
+	}
+
+	if (time < (floater->path_start_time + floater->path->duration))
+	{
+		gdouble path_time;
+
+		path_time = time - floater->path_start_time;
+
+		floater->position =
+		    screen_saver_floater_get_position_from_time (screen_saver, floater,
+		            path_time);
+		floater->scale =
+		    screen_saver_floater_get_scale_from_time (screen_saver, floater, path_time);
+
+		floater->angle =
+		    screen_saver_floater_get_angle_from_time (screen_saver, floater, path_time);
+
+		floater->opacity = pow (floater->scale, 1.0 / GAMMA);
+	}
+	else
+	{
+		path_free (floater->path);
+
+		floater->path = NULL;
+		floater->path_start_time = 0.0;
+	}
+}
+
+static GdkPixbuf *
+gamma_correct (const GdkPixbuf *input_pixbuf)
+{
+	gint x, y, width, height, rowstride;
+	GdkPixbuf *output_pixbuf;
+	guchar *pixels;
+
+	output_pixbuf = gdk_pixbuf_copy (input_pixbuf);
+	pixels = gdk_pixbuf_get_pixels (output_pixbuf);
+
+	width = gdk_pixbuf_get_width (output_pixbuf);
+	height = gdk_pixbuf_get_height (output_pixbuf);
+	rowstride = gdk_pixbuf_get_rowstride (output_pixbuf);
+
+	for (y = 0; y < height; y++)
+		for (x = 0; x < width; x++)
+		{
+			guchar *alpha_channel;
+			guchar opacity;
+
+			alpha_channel = pixels + y * (rowstride / 4) + x + 3;
+			opacity = (guchar) (255 * pow ((*alpha_channel / 255.0), 1.0 / GAMMA));
+
+			*alpha_channel = opacity;
+		}
+
+	return output_pixbuf;
+}
+
+static gboolean
+screen_saver_floater_do_draw (ScreenSaver        *screen_saver,
+                              ScreenSaverFloater *floater,
+                              cairo_t            *context)
+{
+	gint size;
+	CachedSource *source;
+
+	size = CLAMP ((int) (FLOATER_MAX_SIZE * floater->scale),
+	              FLOATER_MIN_SIZE, FLOATER_MAX_SIZE);
+
+	source = g_hash_table_lookup (screen_saver->cached_sources, GINT_TO_POINTER (size));
+
+	if (source == NULL)
+	{
+		GdkPixbuf *pixbuf;
+		GError *error;
+
+		pixbuf = NULL;
+		error = NULL;
+
+		pixbuf = gdk_pixbuf_new_from_file_at_size (screen_saver->filename, size, -1,
+		         &error);
+		if (pixbuf == NULL)
+		{
+			g_assert (error != NULL);
+			g_printerr ("%s", _(error->message));
+			g_error_free (error);
+			return FALSE;
+		}
+
+		if (gdk_pixbuf_get_has_alpha (pixbuf))
+			gamma_correct (pixbuf);
+
+		gdk_cairo_set_source_pixbuf (context, pixbuf, 0.0, 0.0);
+
+		source = cached_source_new (cairo_get_source (context),
+		                            gdk_pixbuf_get_width (pixbuf),
+		                            gdk_pixbuf_get_height (pixbuf));
+		g_object_unref (pixbuf);
+		g_hash_table_insert (screen_saver->cached_sources, GINT_TO_POINTER (size),
+		                     source);
+	}
+
+	cairo_save (context);
+
+	if (screen_saver->should_do_rotations && (fabs (floater->angle) > G_MINDOUBLE))
+	{
+		floater->bounds.width = G_SQRT2 * source->width + 2;
+		floater->bounds.height = G_SQRT2 * source->height + 2;
+		floater->bounds.x = (int) (floater->position.x - .5 * G_SQRT2 * source->width) - 1;
+		floater->bounds.y = (int) (floater->position.y - .5 * G_SQRT2 * source->height) - 1;
+
+		cairo_translate (context,
+		                 trunc (floater->position.x),
+		                 trunc (floater->position.y));
+		cairo_rotate (context, floater->angle);
+		cairo_translate (context,
+		                 -trunc (floater->position.x),
+		                 -trunc (floater->position.y));
+	}
+	else
+	{
+		floater->bounds.width = source->width + 2;
+		floater->bounds.height = source->height + 2;
+		floater->bounds.x = (int) (floater->position.x - .5 * source->width) - 1;
+		floater->bounds.y = (int) (floater->position.y - .5 * source->height) - 1;
+	}
+
+	cairo_translate (context,
+	                 trunc (floater->position.x - .5 * source->width),
+	                 trunc (floater->position.y - .5 * source->height));
+
+	cairo_set_source (context, source->pattern);
+
+	cairo_rectangle (context,
+	                 trunc (.5 * (source->width - floater->bounds.width)),
+	                 trunc (.5 * (source->height - floater->bounds.height)),
+	                 floater->bounds.width, floater->bounds.height);
+
+	cairo_clip (context);
+	cairo_paint_with_alpha (context, floater->opacity);
+	cairo_restore (context);
+
+	if (screen_saver->should_show_paths && (floater->path != NULL))
+	{
+		gdouble dash_pattern[] = { 5.0 };
+
+		cairo_save (context);
+		cairo_set_source_rgba (context, 1.0, 1.0, 1.0, .2 * floater->opacity);
+		cairo_move_to (context,
+		               floater->path->start_point.x,
+		               floater->path->start_point.y);
+		cairo_curve_to (context,
+		                floater->path->start_control_point.x,
+		                floater->path->start_control_point.y,
+		                floater->path->end_control_point.x,
+		                floater->path->end_control_point.y,
+		                floater->path->end_point.x,
+		                floater->path->end_point.y);
+		cairo_set_line_cap (context, CAIRO_LINE_CAP_ROUND);
+		cairo_stroke (context);
+		cairo_set_source_rgba (context, 1.0, 0.0, 0.0, .5 * floater->opacity);
+		cairo_rectangle (context,
+		                 floater->path->start_point.x - 3,
+		                 floater->path->start_point.y - 3,
+		                 6, 6);
+		cairo_fill (context);
+		cairo_set_source_rgba (context, 0.0, 0.5, 0.0, .5 * floater->opacity);
+		cairo_arc (context,
+		           floater->path->start_control_point.x,
+		           floater->path->start_control_point.y,
+		           3, 0.0, 2.0 * G_PI);
+		cairo_stroke (context);
+		cairo_set_source_rgba (context, 0.5, 0.0, 0.5, .5 * floater->opacity);
+		cairo_arc (context,
+		           floater->path->end_control_point.x,
+		           floater->path->end_control_point.y,
+		           3, 0.0, 2.0 * G_PI);
+		cairo_stroke (context);
+		cairo_set_source_rgba (context, 0.0, 0.0, 1.0, .5 * floater->opacity);
+		cairo_rectangle (context,
+		                 floater->path->end_point.x - 3,
+		                 floater->path->end_point.y - 3,
+		                 6, 6);
+		cairo_fill (context);
+
+		cairo_set_dash (context, dash_pattern, G_N_ELEMENTS (dash_pattern), 0);
+		cairo_set_source_rgba (context, .5, .5, .5, .2 * floater->scale);
+		cairo_move_to (context, floater->path->start_point.x,
+		               floater->path->start_point.y);
+		cairo_line_to (context, floater->path->start_control_point.x,
+		               floater->path->start_control_point.y);
+		cairo_stroke (context);
+
+		cairo_move_to (context, floater->path->end_point.x,
+		               floater->path->end_point.y);
+		cairo_line_to (context, floater->path->end_control_point.x,
+		               floater->path->end_control_point.y);
+		cairo_stroke (context);
+
+		cairo_restore (context);
+	}
+
+	return TRUE;
+}
+
+static ScreenSaver *
+screen_saver_new (GtkWidget       *drawing_area,
+                  const gchar     *filename,
+                  gint             max_floater_count,
+                  gboolean         should_do_rotations,
+                  gboolean         should_show_paths)
+{
+	ScreenSaver *screen_saver;
+
+	screen_saver = g_new (ScreenSaver, 1);
+	screen_saver->filename = g_strdup (filename);
+	screen_saver->drawing_area = drawing_area;
+	screen_saver->cached_sources =
+	    g_hash_table_new_full (NULL, NULL, NULL,
+	                           (GDestroyNotify) cached_source_free);
+
+	g_signal_connect_swapped (drawing_area, "size-allocate",
+	                          G_CALLBACK (screen_saver_on_size_allocate),
+	                          screen_saver);
+
+	g_signal_connect_swapped (drawing_area, "draw",
+	                          G_CALLBACK (screen_saver_on_draw),
+	                          screen_saver);
+
+	screen_saver->first_update_time = 0.0;
+	screen_saver->current_calculated_stats_time = 0.0;
+	screen_saver->last_calculated_stats_time = 0.0;
+	screen_saver->update_count = 0;
+	screen_saver->frame_count = 0;
+	screen_saver->updates_per_second = 0.0;
+	screen_saver->frames_per_second = 0.0;
+	screen_saver->floaters = NULL;
+	screen_saver->max_floater_count = max_floater_count;
+
+	screen_saver->should_show_paths = (should_show_paths != FALSE);
+	screen_saver->should_do_rotations = (should_do_rotations != FALSE);
+
+	screen_saver_get_initial_state (screen_saver);
+
+	screen_saver->state_update_timeout_id =
+	    g_timeout_add (1000 / (2.0 * OPTIMAL_FRAME_RATE),
+	                   (GSourceFunc) screen_saver_do_update_state, screen_saver);
+
+	screen_saver->stats_update_timeout_id =
+	    g_timeout_add (1000, (GSourceFunc) screen_saver_do_update_stats,
+	                   screen_saver);
+
+	return screen_saver;
+}
+
+static void
+screen_saver_free (ScreenSaver *screen_saver)
+{
+	if (screen_saver == NULL)
+		return;
+
+	g_free (screen_saver->filename);
+
+	g_hash_table_destroy (screen_saver->cached_sources);
+
+	if (screen_saver->state_update_timeout_id != 0) {
+		g_source_remove (screen_saver->state_update_timeout_id);
+		screen_saver->state_update_timeout_id = 0;
+	}
+
+	if (screen_saver->stats_update_timeout_id != 0) {
+		g_source_remove (screen_saver->stats_update_timeout_id);
+		screen_saver->stats_update_timeout_id = 0;
+	}
+
+	screen_saver_destroy_floaters (screen_saver);
+
+	g_free (screen_saver);
+}
+
+static gdouble
+screen_saver_get_timestamp (ScreenSaver *screen_saver)
+{
+	gint64 now = g_get_real_time ();
+	return (gdouble) now / (gdouble) G_USEC_PER_SEC;
+}
+
+static void
+screen_saver_create_floaters (ScreenSaver *screen_saver)
+{
+	gint i;
+
+	for (i = 0; i < screen_saver->max_floater_count; i++)
+	{
+		ScreenSaverFloater *floater;
+		Point position;
+		gdouble scale;
+
+		position.x = g_random_double_range (screen_saver->canvas_rectangle.top_left_point.x,
+		                                    screen_saver->canvas_rectangle.bottom_right_point.x);
+		position.y = g_random_double_range (screen_saver->canvas_rectangle.top_left_point.y,
+		                                    screen_saver->canvas_rectangle.bottom_right_point.y);
+
+		scale = g_random_double ();
+
+		floater = screen_saver_floater_new (screen_saver, &position, scale);
+
+		screen_saver->floaters = g_list_prepend (screen_saver->floaters,
+		                         floater);
+	}
+}
+
+static gdouble
+screen_saver_get_updates_per_second (ScreenSaver *screen_saver)
+{
+	return screen_saver->updates_per_second;
+}
+
+static gdouble
+screen_saver_get_frames_per_second (ScreenSaver *screen_saver)
+{
+	return screen_saver->frames_per_second;
+}
+
+static gdouble
+screen_saver_get_image_cache_usage (ScreenSaver *screen_saver)
+{
+	static const gdouble cache_capacity = (FLOATER_MAX_SIZE - FLOATER_MIN_SIZE + 1);
+
+	return g_hash_table_size (screen_saver->cached_sources) / cache_capacity;
+}
+
+static void
+screen_saver_destroy_floaters (ScreenSaver *screen_saver)
+{
+	if (screen_saver->floaters == NULL)
+		return;
+
+	g_list_foreach (screen_saver->floaters, (GFunc) screen_saver_floater_free,
+	                NULL);
+	g_list_free (screen_saver->floaters);
+
+	screen_saver->floaters = NULL;
+}
+
+static void
+screen_saver_on_size_allocate (ScreenSaver   *screen_saver,
+                               GtkAllocation *allocation)
+{
+	Rectangle canvas_rectangle;
+
+	canvas_rectangle.top_left_point.x = allocation->x - .1 * allocation->width;
+	canvas_rectangle.top_left_point.y = allocation->y - .1 * allocation->height;
+
+	canvas_rectangle.bottom_right_point.x = allocation->x + (1.1 * allocation->width);
+	canvas_rectangle.bottom_right_point.y = allocation->y + (1.1 * allocation->height);
+
+	screen_saver->canvas_rectangle = canvas_rectangle;
+}
+
+static gint
+compare_floaters (ScreenSaverFloater *a,
+                  ScreenSaverFloater *b)
+{
+	if (a->scale > b->scale)
+		return 1;
+	else if (fabs (a->scale - b->scale) <= G_MINDOUBLE)
+		return 0;
+	else
+		return -1;
+}
+
+static void
+screen_saver_on_draw (ScreenSaver    *screen_saver,
+                      cairo_t        *context)
+{
+	GList *tmp;
+
+	if (screen_saver->floaters == NULL)
+		screen_saver_create_floaters (screen_saver);
+
+	screen_saver->floaters = g_list_sort (screen_saver->floaters,
+	                                      (GCompareFunc)compare_floaters);
+
+	for (tmp = screen_saver->floaters; tmp != NULL; tmp = tmp->next)
+	{
+		ScreenSaverFloater *floater;
+
+		floater = (ScreenSaverFloater *) tmp->data;
+
+		if (!screen_saver_floater_do_draw (screen_saver, floater, context))
+		{
+			gtk_main_quit ();
+			break;
+		}
+	}
+
+	screen_saver->draw_ops_pending = TRUE;
+	screen_saver->frame_count++;
+}
+
+static void
+screen_saver_update_state (ScreenSaver *screen_saver,
+                           gdouble      time)
+{
+	GList *tmp;
+
+	tmp = screen_saver->floaters;
+	while (tmp != NULL)
+	{
+		ScreenSaverFloater *floater;
+		floater = (ScreenSaverFloater *) tmp->data;
+
+		screen_saver_floater_update_state (screen_saver, floater, time);
+
+		if (screen_saver->drawing_area != NULL &&
+		    gtk_widget_get_realized (screen_saver->drawing_area) &&
+		    (floater->bounds.width > 0) && (floater->bounds.height > 0))
+		{
+			gint size;
+			size = CLAMP ((int) (FLOATER_MAX_SIZE * floater->scale),
+			              FLOATER_MIN_SIZE, FLOATER_MAX_SIZE);
+
+			gtk_widget_queue_draw_area (screen_saver->drawing_area,
+			                            floater->bounds.x,
+			                            floater->bounds.y,
+			                            floater->bounds.width,
+			                            floater->bounds.height);
+
+			/* the edges could concievably be spread across two
+			 * pixels so we add +2 to invalidated region
+			 */
+			if (screen_saver->should_do_rotations)
+				gtk_widget_queue_draw_area (screen_saver->drawing_area,
+				                            (int) (floater->position.x -
+				                                   .5 * G_SQRT2 * size),
+				                            (int) (floater->position.y -
+				                                   .5 * G_SQRT2 * size),
+				                            G_SQRT2 * size + 2,
+				                            G_SQRT2 * size + 2);
+			else
+				gtk_widget_queue_draw_area (screen_saver->drawing_area,
+				                            (int) (floater->position.x -
+				                                   .5 * size),
+				                            (int) (floater->position.y -
+				                                   .5 * size),
+				                            size + 2, size + 2);
+
+			if  (screen_saver->should_show_paths)
+				gtk_widget_queue_draw (screen_saver->drawing_area);
+		}
+
+		tmp = tmp->next;
+	}
+}
+
+static void
+screen_saver_get_initial_state (ScreenSaver *screen_saver)
+{
+	screen_saver->first_update_time = screen_saver_get_timestamp (screen_saver);
+	screen_saver_update_state (screen_saver, 0.0);
+}
+
+static gboolean
+screen_saver_do_update_state (ScreenSaver *screen_saver)
+{
+	gdouble current_update_time;
+
+	/* flush pending requests to the X server and block for
+	 * replies before proceeding to help prevent the X server from
+	 * getting overrun with requests
+	 */
+	if (screen_saver->draw_ops_pending)
+	{
+		GdkDisplay *display;
+
+		display = gtk_widget_get_display (GTK_WIDGET(screen_saver->drawing_area));
+		gdk_display_flush (display);
+		screen_saver->draw_ops_pending = FALSE;
+	}
+
+	current_update_time = screen_saver_get_timestamp (screen_saver);
+	screen_saver_update_state (screen_saver, current_update_time -
+	                           screen_saver->first_update_time);
+	screen_saver->update_count++;
+	return TRUE;
+}
+
+static gboolean
+screen_saver_do_update_stats (ScreenSaver *screen_saver)
+{
+	gdouble last_calculated_stats_time, seconds_since_last_stats_update;
+
+	last_calculated_stats_time = screen_saver->current_calculated_stats_time;
+	screen_saver->current_calculated_stats_time =
+	    screen_saver_get_timestamp (screen_saver);
+	screen_saver->last_calculated_stats_time = last_calculated_stats_time;
+
+	if (fabs (last_calculated_stats_time) <= G_MINDOUBLE)
+		return TRUE;
+
+	seconds_since_last_stats_update =
+	    screen_saver->current_calculated_stats_time - last_calculated_stats_time;
+
+	screen_saver->updates_per_second =
+	    screen_saver->update_count / seconds_since_last_stats_update;
+	screen_saver->frames_per_second =
+	    screen_saver->frame_count / seconds_since_last_stats_update;
+
+	screen_saver->update_count = 0;
+	screen_saver->frame_count = 0;
+
+	return TRUE;
+}
+
+static gboolean
+do_print_screen_saver_stats (ScreenSaver *screen_saver)
+{
+
+	g_print ("updates per second: %.2f, frames per second: %.2f, "
+	         "image cache %.0f%% full\n",
+	         screen_saver_get_updates_per_second (screen_saver),
+	         screen_saver_get_frames_per_second (screen_saver),
+	         screen_saver_get_image_cache_usage (screen_saver) * 100.0);
+
+	return TRUE;
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+	ScreenSaver     *screen_saver;
+	GtkWidget       *window;
+	GtkWidget       *drawing_area;
+	gboolean         should_show_paths = FALSE;
+	gboolean         should_do_rotations = FALSE;
+	gboolean         should_print_stats = FALSE;
+	gint             max_floater_count = FLOATER_DEFAULT_COUNT;
+	gchar           *geometry = NULL;
+	gchar          **filenames = NULL;
+	GError          *error = NULL;
+
+	GOptionEntry options[] = {
+	        { "show-paths", 'p', 0, G_OPTION_ARG_NONE, &should_show_paths,
+		  N_("Show paths that images follow"), NULL },
+		{ "do-rotations", 'r', 0, G_OPTION_ARG_NONE, &should_do_rotations,
+		  N_("Occasionally rotate images as they move"), NULL },
+		{ "print-stats", 's', 0, G_OPTION_ARG_NONE, &should_print_stats,
+		  N_("Print out frame rate and other statistics"), NULL },
+		{ "number-of-images", 'n', 0, G_OPTION_ARG_INT, &max_floater_count,
+		  N_("The maximum number of images to keep on screen"), N_("MAX_IMAGES") },
+		{ "geometry", 0, 0, G_OPTION_ARG_STRING, &geometry,
+		  N_("The initial size and position of window"), N_("WIDTHxHEIGHT+X+Y") },
+		{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames,
+		  N_("The source image to use"), NULL },
+		{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
+	};
+
+	bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	gtk_init_with_args (&argc, &argv,
+	                    /* translators: the word "image" here
+	                     * represents a command line argument
+	                     */
+	                    _("image - floats images around the screen"),
+	                    options, GETTEXT_PACKAGE, &error);
+
+	if (error != NULL)
+	{
+		g_printerr (_("%s. See --help for usage information.\n"),
+		            _(error->message));
+		g_error_free (error);
+		return EX_SOFTWARE;
+	}
+
+	if ((filenames == NULL) || (filenames[0] == NULL) ||
+	        (filenames[1] != NULL))
+	{
+		g_printerr (_("You must specify one image.  See --help for usage "
+		              "information.\n"));
+		return EX_USAGE;
+	}
+
+	window = gs_theme_window_new ();
+
+	g_signal_connect (window, "delete-event",
+	                  G_CALLBACK (gtk_main_quit),
+	                  NULL);
+
+	drawing_area = GTK_WIDGET (gtk_drawing_area_new ());
+
+	gtk_widget_show (drawing_area);
+	gtk_container_add (GTK_CONTAINER (window), drawing_area);
+
+	screen_saver = screen_saver_new (drawing_area,
+	                                 filenames[0], max_floater_count,
+	                                 should_do_rotations, should_show_paths);
+	g_strfreev (filenames);
+
+	if (should_print_stats)
+		g_timeout_add (STAT_PRINT_FREQUENCY,
+		               (GSourceFunc) do_print_screen_saver_stats,
+		               screen_saver);
+
+	if ((geometry == NULL)
+	        || !gtk_window_parse_geometry (GTK_WINDOW (window), geometry))
+		gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
+
+	gtk_widget_show (window);
+
+	gtk_main ();
+
+	screen_saver_free (screen_saver);
+
+	return EX_OK;
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/20.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/20.html new file mode 100644 index 0000000..cd549c2 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/20.html @@ -0,0 +1,507 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <glib/gi18n.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include "gs-fade.h"
+#include "gs-debug.h"
+
+#ifdef HAVE_XF86VMODE_GAMMA
+# include <X11/extensions/xf86vmode.h>
+#endif
+
+#define XF86_VIDMODE_NAME "XFree86-VidModeExtension"
+
+static void
+test_fade (void)
+{
+	GSFade *fade;
+	int     reps = 2;
+	int     delay = 2;
+
+	fade = gs_fade_new ();
+
+	while (reps-- > 0)
+	{
+
+		g_print ("fading out...");
+		gs_fade_sync (fade, 1000);
+		g_print ("done.\n");
+
+		g_print ("fading in...");
+		gs_fade_reset (fade);
+		g_print ("done.\n");
+
+		if (delay)
+		{
+			sleep (delay);
+		}
+	}
+
+	g_object_unref (fade);
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+	GError *error = NULL;<--- Assignment 'error=NULL', assigned value is 0
+	int     op, event, err;
+
+#ifdef ENABLE_NLS
+	bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
+# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+# endif
+	textdomain (GETTEXT_PACKAGE);
+#endif
+
+	if (error)<--- Condition 'error' is always false
+	{
+		fprintf (stderr, "%s\n", error->message);
+		exit (1);
+	}
+
+	if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error))
+	{
+		fprintf (stderr, "%s", error->message);
+		g_error_free (error);
+		exit (1);
+	}
+
+	if (! XQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XF86_VIDMODE_NAME, &op, &event, &err))
+	{
+		g_message ("no " XF86_VIDMODE_NAME " extension");
+	}
+	else
+	{
+# ifdef HAVE_XF86VMODE_GAMMA
+		int major;
+		int minor;
+
+		if (! XF86VidModeQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor))
+		{
+			g_message ("unable to get " XF86_VIDMODE_NAME " version");
+		}
+		else
+		{
+			g_message (XF86_VIDMODE_NAME " version %d.%d", major, minor);
+		}
+# else /* !HAVE_XF86VMODE_GAMMA */
+		g_message ("no support for display's " XF86_VIDMODE_NAME " extension");
+# endif /* !HAVE_XF86VMODE_GAMMA */
+	}
+
+	gs_debug_init (TRUE, FALSE);
+
+	test_fade ();
+
+	gs_debug_shutdown ();
+
+	return 0;
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/3.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/3.html new file mode 100644 index 0000000..a607868 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/3.html @@ -0,0 +1,1443 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "gs-theme-engine.h"
+#include "gste-popsquares.h"
+
+static void     gste_popsquares_finalize   (GObject             *object);
+static void     draw_frame                 (GSTEPopsquares      *pop,
+                                            cairo_t *cr);
+
+typedef struct _square
+{
+	int x, y, w, h;
+	int color;
+} square;
+
+struct GSTEPopsquaresPrivate
+{
+	guint timeout_id;
+
+	int        ncolors;
+	int        subdivision;
+
+	GdkRGBA   *colors;
+	square    *squares;
+};
+
+static GObjectClass *parent_class = NULL;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSTEPopsquares, gste_popsquares, GS_TYPE_THEME_ENGINE)
+
+static void
+hsv_to_rgb (int     h,
+            double  s,
+            double  v,
+            double *r,
+            double *g,
+            double *b)
+{
+	double H, S, V, R, G, B;
+	double p1, p2, p3;
+	double f;
+	int    i;
+
+	if (s < 0)
+	{
+		s = 0;
+	}
+	if (v < 0)
+	{
+		v = 0;
+	}
+	if (s > 1)
+	{
+		s = 1;
+	}
+	if (v > 1)
+	{
+		v = 1;
+	}
+
+	S = s;
+	V = v;
+	H = (h % 360) / 60.0;
+	i = H;
+	f = H - i;
+	p1 = V * (1 - S);
+	p2 = V * (1 - (S * f));
+	p3 = V * (1 - (S * (1 - f)));
+
+	if (i == 0)
+	{
+		R = V;
+		G = p3;
+		B = p1;
+	}
+	else if (i == 1)
+	{
+		R = p2;
+		G = V;
+		B = p1;
+	}
+	else if (i == 2)
+	{
+		R = p1;
+		G = V;
+		B = p3;
+	}
+	else if (i == 3)
+	{
+		R = p1;
+		G = p2;
+		B = V;
+	}
+	else if (i == 4)
+	{
+		R = p3;
+		G = p1;
+		B = V;
+	}
+	else
+	{
+		R = V;
+		G = p1;
+		B = p2;
+	}
+
+	*r = R;
+	*g = G;
+	*b = B;
+}
+
+static void
+rgb_to_hsv (double  r,
+            double  g,
+            double  b,
+            int    *h,
+            double *s,
+            double *v)
+{
+	double R, G, B, H, S, V;
+	double cmax, cmin;
+	double cmm;
+	int    imax;
+
+	R = r;
+	G = g;
+	B = b;
+	cmax = R;
+	cmin = G;
+	imax = 1;
+
+	if (cmax < G)
+	{
+		cmax = G;
+		cmin = R;
+		imax = 2;
+	}
+	if (cmax < B)
+	{
+		cmax = B;
+		imax = 3;
+	}
+	if (cmin > B)
+	{
+		cmin = B;
+	}
+
+	cmm = cmax - cmin;
+	V = cmax;
+
+	if (cmm == 0)
+	{
+		S = H = 0;
+	}
+	else
+	{
+		S = cmm / cmax;
+		if (imax == 1)
+		{
+			H = (G - B) / cmm;
+		}
+		else if (imax == 2)
+		{
+			H = 2.0 + (B - R) / cmm;
+		}
+		else
+		{
+			/*if (imax == 3)*/
+			H = 4.0 + (R - G) / cmm;
+		}
+
+		if (H < 0)
+		{
+			H += 6.0;
+		}
+	}
+
+	*h = (H * 60.0);
+	*s = S;
+	*v = V;
+}
+
+static void
+make_color_ramp (int          h1,
+                 double       s1,
+                 double       v1,
+                 int          h2,
+                 double       s2,
+                 double       v2,
+                 GdkRGBA     *colors,
+                 int          n_colors,
+                 gboolean     closed)
+{
+	double   dh, ds, dv;		/* deltas */
+	int      i;
+	int      ncolors, wanted;
+	int      total_ncolors   = n_colors;
+
+	wanted = total_ncolors;
+	if (closed)
+	{
+		wanted = (wanted / 2) + 1;<--- Variable 'wanted' is assigned a value that is never used.
+	}
+
+	ncolors = total_ncolors;
+
+	memset (colors, 0, n_colors * sizeof (*colors));
+
+	if (closed)
+	{
+		ncolors = (ncolors / 2) + 1;
+	}
+
+	/* Note: unlike other routines in this module, this function assumes that
+	   if h1 and h2 are more than 180 degrees apart, then the desired direction
+	   is always from h1 to h2 (rather than the shorter path.)  make_uniform
+	   depends on this.
+	*/
+	dh = ((double)h2 - (double)h1) / ncolors;
+	ds = (s2 - s1) / ncolors;
+	dv = (v2 - v1) / ncolors;
+
+	for (i = 0; i < ncolors; i++)
+	{
+		hsv_to_rgb ((int) (h1 + (i * dh)),
+		            (s1 + (i * ds)),
+		            (v1 + (i * dv)),
+		            &colors [i].red,
+		            &colors [i].green,
+		            &colors [i].blue);
+		colors [i].alpha = 1.0;
+	}
+
+	if (closed)
+	{
+		for (i = ncolors; i < n_colors; i++)
+		{
+			colors [i] = colors [n_colors - i];
+		}
+	}
+
+}
+
+static void
+randomize_square_colors (square *squares,
+                         int     nsquares,
+                         int     ncolors)
+{
+	int     i;
+	square *s;
+
+	s = squares;
+
+	for (i = 0; i < nsquares; i++)
+	{
+		s[i].color = g_random_int_range (0, ncolors);
+	}
+}
+
+static void
+set_colors (GtkWidget *widget,
+            GdkRGBA   *fg,
+            GdkRGBA   *bg)
+{
+	GtkStyleContext  *style;
+
+	style = gtk_widget_get_style_context (widget);
+
+	gtk_style_context_save (style);
+	gtk_style_context_set_state (style, GTK_STATE_FLAG_SELECTED);
+	gtk_style_context_get_background_color (style,
+	                                        gtk_style_context_get_state (style),
+	                                        bg);
+	if (bg->alpha == 0.0)
+	{
+		gtk_style_context_add_class (style, GTK_STYLE_CLASS_VIEW);
+		gtk_style_context_get_background_color (style,
+		                                        gtk_style_context_get_state (style),
+		                                        bg);
+	}
+	gtk_style_context_restore (style);
+
+	fg->red   = bg->red * 0.7;
+	fg->green = bg->green * 0.7;
+	fg->blue  = bg->blue * 0.7;
+	fg->alpha = bg->alpha;
+}
+
+static void
+gste_popsquares_set_property (GObject            *object,
+                              guint               prop_id,
+                              const GValue       *value,
+                              GParamSpec         *pspec)
+{
+	GSTE_POPSQUARES (object);
+
+	switch (prop_id)
+	{
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gste_popsquares_get_property (GObject            *object,
+                              guint               prop_id,
+                              GValue             *value,
+                              GParamSpec         *pspec)
+{
+	GSTE_POPSQUARES (object);
+
+	switch (prop_id)
+	{
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+setup_squares (GSTEPopsquares *pop)
+{
+	int       window_width;
+	int       window_height;
+	int       nsquares;
+	int       x, y;
+	int       sw, sh, gw, gh;
+	GdkWindow *window;
+
+	window = gs_theme_engine_get_window (GS_THEME_ENGINE (pop));
+
+	if (window == NULL)
+	{
+		return;
+	}
+
+	gs_theme_engine_get_window_size (GS_THEME_ENGINE (pop), &window_width, &window_height);
+
+	sw = window_width / pop->priv->subdivision;
+	sh = window_height / pop->priv->subdivision;
+
+	gw = pop->priv->subdivision;
+	gh = pop->priv->subdivision;
+	nsquares = gw * gh;
+
+	if (pop->priv->squares)
+	{
+		g_free (pop->priv->squares);
+	}
+	pop->priv->squares = g_new0 (square, nsquares);
+
+	for (y = 0; y < gh; y++)
+	{
+		for (x = 0; x < gw; x++)
+		{
+			square *s = (square *) &pop->priv->squares [gw * y + x];
+			s->w = sw;
+			s->h = sh;
+			s->x = x * sw;
+			s->y = y * sh;
+		}
+	}
+}
+
+static void
+setup_colors (GSTEPopsquares *pop)
+{
+	double    s1, v1, s2, v2 = 0;
+	int       h1, h2 = 0;
+	int       nsquares;
+	GdkRGBA   fg;
+	GdkRGBA   bg;
+	GdkWindow *window;
+
+	window = gs_theme_engine_get_window (GS_THEME_ENGINE (pop));
+
+	if (window == NULL)
+	{
+		return;
+	}
+
+	set_colors (GTK_WIDGET (pop), &fg, &bg);
+
+	if (pop->priv->colors)
+	{
+		g_free (pop->priv->colors);
+	}
+	pop->priv->colors = g_new0 (GdkRGBA, pop->priv->ncolors);
+
+	rgb_to_hsv (fg.red, fg.green, fg.blue, &h1, &s1, &v1);
+	rgb_to_hsv (bg.red, bg.green, bg.blue, &h2, &s2, &v2);
+
+	make_color_ramp (h1, s1, v1,
+	                 h2, s2, v2,
+	                 pop->priv->colors,
+	                 pop->priv->ncolors,
+	                 TRUE);
+
+	nsquares = pop->priv->subdivision * pop->priv->subdivision;
+
+	randomize_square_colors (pop->priv->squares, nsquares, pop->priv->ncolors);
+}
+
+static void
+gste_popsquares_real_show (GtkWidget *widget)
+{
+	GSTEPopsquares *pop = GSTE_POPSQUARES (widget);
+
+	/* start */
+	setup_squares (pop);
+	setup_colors (pop);
+
+	if (GTK_WIDGET_CLASS (parent_class)->show)
+	{
+		GTK_WIDGET_CLASS (parent_class)->show (widget);
+	}
+}
+
+static gboolean
+gste_popsquares_real_draw (GtkWidget *widget,
+                           cairo_t   *cr)
+{
+	if (GTK_WIDGET_CLASS (parent_class)->draw) {
+		GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
+	}
+
+	draw_frame (GSTE_POPSQUARES (widget), cr);
+
+	return TRUE;
+}
+
+static gboolean
+gste_popsquares_real_configure (GtkWidget         *widget,
+                                GdkEventConfigure *event)
+{
+	GSTEPopsquares *pop = GSTE_POPSQUARES (widget);
+	gboolean        handled = FALSE;
+
+	/* resize */
+
+	/* just reset everything */
+	setup_squares (pop);
+	setup_colors (pop);
+
+	/* schedule a redraw */
+	gtk_widget_queue_draw (widget);
+
+	if (GTK_WIDGET_CLASS (parent_class)->configure_event)
+	{
+		handled = GTK_WIDGET_CLASS (parent_class)->configure_event (widget, event);
+	}
+
+	return handled;
+}
+
+static void
+gste_popsquares_class_init (GSTEPopsquaresClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	object_class->finalize = gste_popsquares_finalize;
+	object_class->get_property = gste_popsquares_get_property;
+	object_class->set_property = gste_popsquares_set_property;
+
+	widget_class->show = gste_popsquares_real_show;
+	widget_class->draw = gste_popsquares_real_draw;
+	widget_class->configure_event = gste_popsquares_real_configure;
+}
+
+static void
+draw_frame (GSTEPopsquares *pop,
+            cairo_t        *cr)
+{
+	int      border = 1;
+	gboolean twitch = FALSE;
+	int      x, y;
+	int      gw, gh;
+	int      nsquares;
+	int      window_width;
+	int      window_height;
+	GdkWindow *window;
+
+	window = gs_theme_engine_get_window (GS_THEME_ENGINE (pop));
+
+	if (window == NULL)
+	{
+		return;
+	}
+
+	gs_theme_engine_get_window_size (GS_THEME_ENGINE (pop),
+	                                 &window_width,
+	                                 &window_height);
+
+	gw = pop->priv->subdivision;
+	gh = pop->priv->subdivision;
+	nsquares = gw * gh;
+
+	for (y = 0; y < gh; y++)
+	{
+		for (x = 0; x < gw; x++)
+		{
+			square *s = (square *) &pop->priv->squares [gw * y + x];
+
+			gdk_cairo_set_source_rgba (cr, &(pop->priv->colors [s->color]));
+			cairo_rectangle (cr, s->x, s->y,
+			                 border ? s->w - border : s->w,
+			                 border ? s->h - border : s->h);
+			cairo_fill (cr);
+			s->color++;
+
+			if (s->color == pop->priv->ncolors)
+			{
+				if (twitch && ((g_random_int_range (0, 4)) == 0))
+				{
+					randomize_square_colors (pop->priv->squares, nsquares, pop->priv->ncolors);
+				}
+				else
+				{
+					s->color = g_random_int_range (0, pop->priv->ncolors);
+				}
+			}
+		}
+	}
+}
+
+static gboolean
+draw_iter (GSTEPopsquares *pop)
+{
+	gtk_widget_queue_draw (GTK_WIDGET (pop));
+	return TRUE;
+}
+
+static void
+gste_popsquares_init (GSTEPopsquares *pop)
+{
+	int delay;
+
+	pop->priv = gste_popsquares_get_instance_private (pop);
+
+	pop->priv->ncolors = 128;
+	pop->priv->subdivision = 5;
+
+	delay = 25;
+	pop->priv->timeout_id = g_timeout_add (delay, (GSourceFunc)draw_iter, pop);
+}
+
+static void
+gste_popsquares_finalize (GObject *object)
+{
+	GSTEPopsquares *pop;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GSTE_IS_POPSQUARES (object));
+
+	pop = GSTE_POPSQUARES (object);
+
+	g_return_if_fail (pop->priv != NULL);
+
+	if (pop->priv->timeout_id > 0)
+	{
+		g_source_remove (pop->priv->timeout_id);
+		pop->priv->timeout_id = 0;
+	}
+
+	g_free (pop->priv->squares);
+	g_free (pop->priv->colors);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/4.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/4.html new file mode 100644 index 0000000..d3f91b2 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/4.html @@ -0,0 +1,2335 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*-
+ *
+ * Copyright (C) 2005-2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "gs-theme-engine.h"
+#include "gste-slideshow.h"
+
+static void     gste_slideshow_finalize   (GObject            *object);
+
+struct GSTESlideshowPrivate
+{
+	/* Image at full opacity */
+	cairo_pattern_t *pat1;
+	/* Image at partial opacity */
+	cairo_pattern_t *pat2;
+	/* Alpha of pat2 */
+	gdouble          alpha2;
+	/* edges of pat2 */
+	int              pat2top;
+	int              pat2bottom;
+	int              pat2left;
+	int              pat2right;
+
+	/* backbuffer that we do all the alpha drawing into (no round
+	 * trips to the X server when the server doesn't support drawing
+	 * pixmaps with alpha?) */
+	cairo_surface_t *surf;
+
+	gint64           fade_ticks;
+
+	GThread         *load_thread;
+	GAsyncQueue     *op_q;
+	GAsyncQueue     *results_q;
+
+	guint           results_pull_id;
+	guint           update_image_id;
+
+	GSList         *filename_list;
+	char           *images_location;
+	gboolean        sort_images;
+	int             window_width;
+	int             window_height;
+	PangoColor     *background_color;
+	gboolean        no_stretch_hint;
+
+	guint           timeout_id;
+
+	GTimer         *timer;
+	gboolean        fade_disabled;
+};
+
+enum
+{
+    PROP_0,
+    PROP_IMAGES_LOCATION,
+    PROP_SORT_IMAGES,
+    PROP_SOLID_BACKGROUND,
+    PROP_NO_STRETCH_HINT
+};
+
+static GObjectClass *parent_class = NULL;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSTESlideshow, gste_slideshow, GS_TYPE_THEME_ENGINE)<--- There is an unknown macro here somewhere. Configuration is required. If G_DEFINE_TYPE_WITH_PRIVATE is a macro then please configure it.
+
+#define N_FADE_TICKS 10
+#define MINIMUM_FPS 3.0
+#define DEFAULT_IMAGES_LOCATION DATADIR "/pixmaps/backgrounds"
+#define IMAGE_LOAD_TIMEOUT 10000
+
+typedef struct _Op
+{
+	char          *location;
+	GSTESlideshow *slideshow;
+} Op;
+
+typedef struct _OpResult
+{
+	GdkPixbuf *pixbuf;
+} OpResult;
+
+static gboolean
+push_load_image_func (GSTESlideshow *show)
+{
+	Op *op;
+
+	gs_theme_engine_profile_msg ("Starting a new image load");
+
+	op = g_new (Op, 1);
+
+	op->location = g_strdup (show->priv->images_location);
+	op->slideshow = g_object_ref (show);
+
+	g_async_queue_push (show->priv->op_q, op);
+
+	show->priv->update_image_id = 0;
+
+	return FALSE;
+}
+
+static void
+start_new_load (GSTESlideshow *show,
+                guint          timeout)
+{
+	gs_theme_engine_profile_msg ("Scheduling a new image load");
+
+	/* queue a new load */
+	if (show->priv->update_image_id <= 0)
+	{
+		show->priv->update_image_id = g_timeout_add_full (G_PRIORITY_LOW, timeout,
+		                              (GSourceFunc)push_load_image_func,
+		                              show, NULL);
+	}
+}
+
+static void
+start_fade (GSTESlideshow *show,
+            GdkPixbuf     *pixbuf)
+{
+	int      pw;
+	int      ph;
+	int      x;
+	int      y;
+	cairo_t *cr;
+	int      window_width;
+	int      window_height;
+
+	gs_theme_engine_profile_start ("start");
+
+	window_width = show->priv->window_width;
+	window_height = show->priv->window_height;
+
+	if (show->priv->pat2 != NULL)
+	{
+		cairo_pattern_destroy (show->priv->pat2);
+	}
+
+	pw = gdk_pixbuf_get_width (pixbuf);
+	ph = gdk_pixbuf_get_height (pixbuf);
+	x = (window_width - pw) / 2;
+	y = (window_height - ph) / 2;
+
+	if (gdk_pixbuf_get_has_alpha (pixbuf) && show->priv->background_color)
+	{
+		GdkPixbuf *colored;
+		guint32    color;
+
+		color = (show->priv->background_color->red << 16)
+		        + (show->priv->background_color->green / 256 << 8)
+		        + show->priv->background_color->blue / 256;
+		colored = gdk_pixbuf_composite_color_simple (pixbuf,
+		          pw, ph,
+		          GDK_INTERP_BILINEAR,
+		          255,
+		          256,
+		          color,
+		          color);
+
+		gdk_pixbuf_copy_area (colored, 0, 0,
+		                      gdk_pixbuf_get_width (colored),
+		                      gdk_pixbuf_get_height (colored),
+		                      pixbuf, 0, 0);
+
+		g_object_unref(colored);
+	}
+
+	cr = cairo_create (show->priv->surf);
+
+	/* XXX Handle out of memory? */
+	gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
+	show->priv->pat2 = cairo_pattern_reference (cairo_get_source (cr));
+	show->priv->pat2top = y;
+	show->priv->pat2bottom = y + ph;
+	show->priv->pat2left = x;
+	show->priv->pat2right = x + pw;
+
+	cairo_destroy (cr);
+
+	show->priv->fade_ticks = 0;
+	g_timer_start (show->priv->timer);
+
+	gs_theme_engine_profile_end ("end");
+}
+
+static void
+finish_fade (GSTESlideshow *show)
+{
+	gs_theme_engine_profile_start ("start");
+
+	if (show->priv->pat1 != NULL)
+	{
+		cairo_pattern_destroy (show->priv->pat1);
+	}
+
+	show->priv->pat1 = show->priv->pat2;
+	show->priv->pat2 = NULL;
+
+	start_new_load (show, IMAGE_LOAD_TIMEOUT);
+
+	gs_theme_engine_profile_end ("end");
+}
+
+static void
+update_display (GSTESlideshow *show)
+{
+	int      window_width;
+	int      window_height;
+	cairo_t *cr;
+
+	gs_theme_engine_profile_start ("start");
+
+	cr = cairo_create (show->priv->surf);
+
+	gs_theme_engine_get_window_size (GS_THEME_ENGINE (show),
+	                                 &window_width,
+	                                 &window_height);
+
+	if (show->priv->pat2 != NULL)
+	{
+		/* fade out areas not covered by the new image */
+		/* top */
+		cairo_rectangle (cr, 0, 0, window_width, show->priv->pat2top);
+		if (show->priv->background_color)
+		{
+			cairo_set_source_rgba (cr, show->priv->background_color->red / 65535.0,
+			                       show->priv->background_color->green / 65535.0,
+			                       show->priv->background_color->blue / 65535.0, show->priv->alpha2);
+		}
+		else
+		{
+			cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, show->priv->alpha2);
+		}
+		cairo_fill (cr);
+		/* left (excluding what's covered by top and bottom) */
+		cairo_rectangle (cr, 0, show->priv->pat2top,
+		                 show->priv->pat2left,
+		                 show->priv->pat2bottom - show->priv->pat2top);
+		if (show->priv->background_color)
+		{
+			cairo_set_source_rgba (cr, show->priv->background_color->red / 65535.0,
+			                       show->priv->background_color->green / 65535.0,
+			                       show->priv->background_color->blue / 65535.0, show->priv->alpha2);
+		}
+		else
+		{
+			cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, show->priv->alpha2);
+		}
+		cairo_fill (cr);
+		/* bottom */
+		cairo_rectangle (cr, 0, show->priv->pat2bottom, window_width,
+		                 window_height - show->priv->pat2bottom);
+		if (show->priv->background_color)
+		{
+			cairo_set_source_rgba (cr, show->priv->background_color->red / 65535.0,
+			                       show->priv->background_color->green / 65535.0,
+			                       show->priv->background_color->blue / 65535.0, show->priv->alpha2);
+		}
+		else
+		{
+			cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, show->priv->alpha2);
+		}
+		cairo_fill (cr);
+		/* right (excluding what's covered by top and bottom) */
+		cairo_rectangle (cr, show->priv->pat2right,
+		                 show->priv->pat2top,
+		                 window_width - show->priv->pat2right,
+		                 show->priv->pat2bottom - show->priv->pat2top);
+		if (show->priv->background_color)
+		{
+			cairo_set_source_rgba (cr, show->priv->background_color->red / 65535.0,
+			                       show->priv->background_color->green / 65535.0,
+			                       show->priv->background_color->blue / 65535.0, show->priv->alpha2);
+		}
+		else
+		{
+			cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, show->priv->alpha2);
+		}
+		cairo_fill (cr);
+
+		gs_theme_engine_profile_start ("paint pattern to surface");
+		cairo_set_source (cr, show->priv->pat2);
+
+		cairo_paint_with_alpha (cr, show->priv->alpha2);
+		gs_theme_engine_profile_end ("paint pattern to surface");
+	}
+	else
+	{
+		if (show->priv->pat1 != NULL)
+		{
+			cairo_set_source (cr, show->priv->pat1);
+			cairo_paint (cr);
+		}
+	}
+
+	cairo_destroy (cr);
+
+	gtk_widget_queue_draw (GTK_WIDGET (show));
+}
+
+static gboolean
+draw_iter (GSTESlideshow *show)
+{
+	double old_opacity;
+	double new_opacity;
+
+	if (show->priv->pat2 != NULL)
+	{
+		gdouble fps;
+		gdouble elapsed;
+
+		if (show->priv->fade_disabled)
+		{
+			show->priv->alpha2 = 1.0;
+			update_display (show);
+			finish_fade (show);
+			return TRUE;
+		}
+
+		/* we are in a fade */
+		show->priv->fade_ticks++;
+
+		/*
+		 * We have currently drawn pat2 with old_opacity, and we
+		 * want to set alpha2 so that drawing pat2 at alpha2
+		 * yields it drawn with new_opacity
+		 *
+		 * Solving
+		 *   new_opacity = 1 - (1 - alpha2) * (1 - old_opacity)
+		 * yields
+		 *   alpha2 = 1 - (1 - new_opacity) / (1 - old_opacity)
+		 *
+		 * XXX This assumes that cairo doesn't correct alpha for
+		 * the color profile.  However, any error is guaranteed
+		 * to be cleaned up by the last iteration, where alpha2
+		 * becomes 1 because new_opacity is 1.
+		 */
+		old_opacity = (double) (show->priv->fade_ticks - 1) /
+		              (double) N_FADE_TICKS;
+		new_opacity = (double) show->priv->fade_ticks /
+		              (double) N_FADE_TICKS;
+		show->priv->alpha2 = 1.0 - (1.0 - new_opacity) /
+		                     (1.0 - old_opacity);
+
+		update_display (show);
+
+		elapsed = g_timer_elapsed (show->priv->timer, NULL);
+		fps = (gdouble)show->priv->fade_ticks / elapsed;
+		if (fps < MINIMUM_FPS)
+		{
+			g_warning ("Getting less than %.2f frames per second, disabling fade", MINIMUM_FPS);
+			show->priv->fade_ticks = N_FADE_TICKS - 1;
+			show->priv->fade_disabled = TRUE;
+		}
+
+		if (show->priv->fade_ticks >= N_FADE_TICKS)
+		{
+			finish_fade (show);
+		}
+	}
+
+	return TRUE;
+}
+
+static void
+process_new_pixbuf (GSTESlideshow *show,
+                    GdkPixbuf     *pixbuf)
+{
+	gs_theme_engine_profile_msg ("Processing a new image");
+
+	if (pixbuf != NULL)
+	{
+		start_fade (show, pixbuf);
+	}
+	else
+	{
+		start_new_load (show, 10);
+	}
+}
+
+static void
+op_result_free (OpResult *result)
+{
+	if (result == NULL)
+	{
+		return;
+	}
+
+	if (result->pixbuf != NULL)
+	{
+		g_object_unref (result->pixbuf);
+	}
+
+	g_free (result);
+}
+
+static gboolean
+results_pull_func (GSTESlideshow *show)
+{
+	OpResult *result;
+
+	g_async_queue_lock (show->priv->results_q);
+
+	result = g_async_queue_try_pop_unlocked (show->priv->results_q);
+	g_assert (result);
+
+	while (result != NULL)
+	{
+		process_new_pixbuf (show, result->pixbuf);
+		op_result_free (result);
+
+		result = g_async_queue_try_pop_unlocked (show->priv->results_q);
+	}
+
+	show->priv->results_pull_id = 0;
+
+	g_async_queue_unlock (show->priv->results_q);
+
+	return FALSE;
+}
+
+static GdkPixbuf *
+scale_pixbuf (GdkPixbuf *pixbuf,
+              int        max_width,
+              int        max_height,
+              gboolean   no_stretch_hint)
+{
+	int        pw;
+	int        ph;
+	float      scale_factor_x = 1.0;
+	float      scale_factor_y = 1.0;
+	float      scale_factor = 1.0;
+
+	pw = gdk_pixbuf_get_width (pixbuf);
+	ph = gdk_pixbuf_get_height (pixbuf);
+
+	/* If the image is less than 256 wide or high then it
+	   is probably a thumbnail and we should ignore it */
+	if (pw < 256 || ph < 256)
+	{
+		return NULL;
+	}
+
+	/* Determine which dimension requires the smallest scale. */
+	scale_factor_x = (float) max_width / (float) pw;
+	scale_factor_y = (float) max_height / (float) ph;
+
+	if (scale_factor_x > scale_factor_y)
+	{
+		scale_factor = scale_factor_y;
+	}
+	else
+	{
+		scale_factor = scale_factor_x;
+	}
+
+	/* always scale down, allow to disable scaling up */
+	if (scale_factor < 1.0 || !no_stretch_hint)
+	{
+		int scale_x;
+		int scale_y;
+
+		scale_x = (int) (pw * scale_factor);
+		scale_y = (int) (ph * scale_factor);
+		return gdk_pixbuf_scale_simple (pixbuf,
+		                                scale_x,
+		                                scale_y,
+		                                GDK_INTERP_BILINEAR);
+	}
+	else
+	{
+		return g_object_ref (pixbuf);
+	}
+}
+
+static void
+add_files_to_list (GSList    **list,
+                   const char *base)
+{
+	GDir       *d;
+	const char *d_name;
+
+	d = g_dir_open (base, 0, NULL);
+	if (d == NULL)
+	{
+		g_warning ("Could not open directory: %s", base);
+		return;
+	}
+
+	while ((d_name = g_dir_read_name (d)) != NULL)
+	{
+		char *path;
+
+		/* skip hidden files */
+		if (d_name[0] == '.')
+		{
+			continue;
+		}
+
+		path = g_build_filename (base, d_name, NULL);
+		if (g_file_test (path, G_FILE_TEST_IS_DIR))
+		{
+			add_files_to_list (list, path);
+			g_free (path);
+		}
+		else
+		{
+			*list = g_slist_prepend (*list, path);
+		}
+	}
+
+	g_dir_close (d);
+}
+
+static GSList *
+build_filename_list_local_dir (const char *base)
+{
+	GSList *list = NULL;
+
+	add_files_to_list (&list, base);
+
+	return list;
+}
+
+static int
+gste_strcmp_compare_func (gconstpointer string_a, gconstpointer string_b)
+{
+	return strcmp (string_a == NULL ? "" : string_a,
+	               string_b == NULL ? "" : string_b);
+}
+
+static GdkPixbuf *
+get_pixbuf_from_local_dir (GSTESlideshow *show,
+                           const char    *location)
+{
+	GdkPixbuf *pixbuf, *transformed_pixbuf;
+	char      *filename;
+	int        i;
+	GSList    *l;
+
+	/* rebuild the cache */
+	if (show->priv->filename_list == NULL)
+	{
+		show->priv->filename_list = build_filename_list_local_dir (location);
+	}
+
+	if (show->priv->filename_list == NULL)
+	{
+		return NULL;
+	}
+	else
+	{
+		if (show->priv->sort_images)
+		{
+			show->priv->filename_list = g_slist_sort (show->priv->filename_list, gste_strcmp_compare_func);
+		}
+	}
+
+	/* get a random filename if needed */
+	if (! show->priv->sort_images)
+	{
+		i = g_random_int_range (0, g_slist_length (show->priv->filename_list));
+		l = g_slist_nth (show->priv->filename_list, i);
+	}
+	else
+	{
+		l = show->priv->filename_list;
+	}
+	filename = l->data;
+
+	pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
+
+	if (pixbuf != NULL)
+	{
+		transformed_pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf);
+		g_object_unref (pixbuf);
+	}
+	else
+	{
+		transformed_pixbuf = NULL;
+	}
+
+	g_free (filename);
+	show->priv->filename_list = g_slist_delete_link (show->priv->filename_list, l);
+
+	return transformed_pixbuf;
+}
+
+static GdkPixbuf *
+get_pixbuf_from_location (GSTESlideshow *show,
+                          const char    *location)
+{
+	GdkPixbuf *pixbuf = NULL;
+	gboolean   is_dir;
+
+	if (location == NULL)
+	{
+		return NULL;
+	}
+
+	is_dir = g_file_test (location, G_FILE_TEST_IS_DIR);
+
+	if (is_dir)
+	{
+		pixbuf = get_pixbuf_from_local_dir (show, location);
+	}
+
+	return pixbuf;
+}
+
+static GdkPixbuf *
+get_pixbuf (GSTESlideshow *show,
+            const char    *location,
+            int            width,
+            int            height)
+{
+	GdkPixbuf *pixbuf;
+	GdkPixbuf *scaled = NULL;
+
+	if (location == NULL)
+	{
+		return NULL;
+	}
+
+	pixbuf = get_pixbuf_from_location (show, location);
+
+	if (pixbuf != NULL)
+	{
+		scaled = scale_pixbuf (pixbuf, width, height, show->priv->no_stretch_hint);
+		g_object_unref (pixbuf);
+	}
+
+	return scaled;
+}
+
+static void
+op_load_image (GSTESlideshow *show,
+               const char    *location)
+{
+	OpResult *op_result;
+	int       window_width;
+	int       window_height;
+
+	window_width = show->priv->window_width;
+	window_height = show->priv->window_height;
+
+	op_result = g_new0 (OpResult, 1);
+
+	op_result->pixbuf = get_pixbuf (show,
+	                                location,
+	                                window_width,
+	                                window_height);
+
+	g_async_queue_lock (show->priv->results_q);
+	g_async_queue_push_unlocked (show->priv->results_q, op_result);
+
+	if (show->priv->results_pull_id == 0)
+	{
+		show->priv->results_pull_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+		                              (GSourceFunc)results_pull_func,
+		                              show, NULL);
+	}
+
+	g_async_queue_unlock (show->priv->results_q);
+}
+
+static gpointer
+load_threadfunc (GAsyncQueue *op_q)
+{
+	Op *op;
+
+	op = g_async_queue_pop (op_q);
+	while (op)
+	{
+		op_load_image (op->slideshow,
+		               op->location);
+
+		if (op->slideshow != NULL)
+		{
+			g_object_unref (op->slideshow);
+		}
+		g_free (op->location);
+		g_free (op);
+
+		op = g_async_queue_pop (op_q);
+	}
+
+	return NULL;
+}
+
+void
+gste_slideshow_set_images_location (GSTESlideshow *show,
+                                    const char    *location)
+{
+	g_return_if_fail (GSTE_IS_SLIDESHOW (show));
+
+	g_free (show->priv->images_location);
+	show->priv->images_location = g_strdup (location);
+}
+
+void
+gste_slideshow_set_sort_images (GSTESlideshow *show,
+                                gboolean       sort_images)
+{
+	g_return_if_fail (GSTE_IS_SLIDESHOW (show));
+
+	show->priv->sort_images = sort_images;
+}
+
+void
+gste_slideshow_set_no_stretch_hint (GSTESlideshow *show,
+                                    gboolean       no_stretch_hint)
+{
+	g_return_if_fail (GSTE_IS_SLIDESHOW (show));
+
+	show->priv->no_stretch_hint = no_stretch_hint;
+}
+
+void
+gste_slideshow_set_background_color (GSTESlideshow *show,
+                                     const char    *background_color)
+{
+	g_return_if_fail (GSTE_IS_SLIDESHOW (show));
+
+	if (show->priv->background_color != NULL)
+	{
+		g_slice_free (PangoColor, show->priv->background_color);
+		show->priv->background_color = NULL;
+	}
+
+	if (background_color != NULL)
+	{
+		show->priv->background_color = g_slice_new (PangoColor);
+
+		if (pango_color_parse (show->priv->background_color, background_color) == FALSE)
+		{
+			g_slice_free (PangoColor, show->priv->background_color);
+			show->priv->background_color = NULL;
+		}
+	}
+}
+
+static void
+gste_slideshow_set_property (GObject            *object,
+                             guint               prop_id,
+                             const GValue       *value,
+                             GParamSpec         *pspec)
+{
+	GSTESlideshow *self;
+
+	self = GSTE_SLIDESHOW (object);
+
+	switch (prop_id)
+	{
+	case PROP_IMAGES_LOCATION:
+		gste_slideshow_set_images_location (self, g_value_get_string (value));
+		break;
+	case PROP_SORT_IMAGES:
+		gste_slideshow_set_sort_images (self, g_value_get_boolean (value));
+		break;
+	case PROP_SOLID_BACKGROUND:
+		gste_slideshow_set_background_color (self, g_value_get_string (value));
+		break;
+	case PROP_NO_STRETCH_HINT:
+		gste_slideshow_set_no_stretch_hint (self, g_value_get_boolean (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gste_slideshow_get_property (GObject            *object,
+                             guint               prop_id,
+                             GValue             *value,
+                             GParamSpec         *pspec)
+{
+	GSTESlideshow *self;
+
+	self = GSTE_SLIDESHOW (object);
+
+	switch (prop_id)
+	{
+	case PROP_IMAGES_LOCATION:
+		g_value_set_string (value, self->priv->images_location);
+		break;
+	case PROP_SORT_IMAGES:
+		g_value_set_boolean (value, self->priv->sort_images);
+		break;
+	case PROP_SOLID_BACKGROUND:
+	{
+		char *color = NULL;
+		color = pango_color_to_string (self->priv->background_color);
+		g_value_set_string (value, color);
+		g_free (color);
+		break;
+	}
+	case PROP_NO_STRETCH_HINT:
+		g_value_set_boolean (value, self->priv->no_stretch_hint);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gste_slideshow_real_show (GtkWidget *widget)
+{
+	GSTESlideshow *show = GSTE_SLIDESHOW (widget);
+	int            delay;
+
+	if (GTK_WIDGET_CLASS (parent_class)->show)
+	{
+		GTK_WIDGET_CLASS (parent_class)->show (widget);
+	}
+
+	start_new_load (show, 10);
+
+	delay = 25;
+	show->priv->timeout_id = g_timeout_add (delay, (GSourceFunc)draw_iter, show);
+
+	if (show->priv->timer != NULL)
+	{
+		g_timer_destroy (show->priv->timer);
+	}
+	show->priv->timer = g_timer_new ();
+}
+
+static gboolean
+gste_slideshow_real_draw (GtkWidget *widget,
+                          cairo_t   *cr)
+{
+	GSTESlideshow *show = GSTE_SLIDESHOW (widget);
+
+	if (GTK_WIDGET_CLASS (parent_class)->draw) {
+		GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
+	}
+
+	cairo_set_source_surface (cr, show->priv->surf, 0, 0);
+
+	gs_theme_engine_profile_start ("paint surface to window");
+	cairo_paint (cr);
+	gs_theme_engine_profile_end ("paint surface to window");
+
+	return TRUE;
+}
+
+static gboolean
+gste_slideshow_real_configure (GtkWidget         *widget,
+                               GdkEventConfigure *event)
+{
+	GSTESlideshow *show = GSTE_SLIDESHOW (widget);
+	gboolean       handled = FALSE;
+	cairo_t       *cr;
+
+	/* resize */
+	gs_theme_engine_get_window_size (GS_THEME_ENGINE (show),
+	                                 &show->priv->window_width,
+	                                 &show->priv->window_height);
+
+	gs_theme_engine_profile_msg ("Resize to x:%d y:%d",
+	                             show->priv->window_width,
+	                             show->priv->window_height);
+
+	if (show->priv->surf != NULL)
+	{
+		cairo_surface_destroy (show->priv->surf);
+	}
+
+	cr = gdk_cairo_create (gtk_widget_get_window (widget));
+	show->priv->surf = cairo_surface_create_similar (cairo_get_target (cr),
+	                   CAIRO_CONTENT_COLOR,
+	                   show->priv->window_width,
+	                   show->priv->window_height);
+	cairo_destroy (cr);
+
+	/* schedule a redraw */
+	gtk_widget_queue_draw (widget);
+
+	if (GTK_WIDGET_CLASS (parent_class)->configure_event)
+	{
+		handled = GTK_WIDGET_CLASS (parent_class)->configure_event (widget, event);
+	}
+
+	return handled;
+}
+
+static void
+gste_slideshow_class_init (GSTESlideshowClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	object_class->finalize = gste_slideshow_finalize;
+	object_class->get_property = gste_slideshow_get_property;
+	object_class->set_property = gste_slideshow_set_property;
+
+	widget_class->show = gste_slideshow_real_show;
+	widget_class->draw = gste_slideshow_real_draw;
+	widget_class->configure_event = gste_slideshow_real_configure;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_IMAGES_LOCATION,
+	                                 g_param_spec_string ("images-location",
+	                                         NULL,
+	                                         NULL,
+	                                         NULL,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_SORT_IMAGES,
+	                                 g_param_spec_boolean ("sort-images",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_SOLID_BACKGROUND,
+	                                 g_param_spec_string ("background-color",
+	                                         NULL,
+	                                         NULL,
+	                                         NULL,
+	                                         G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_NO_STRETCH_HINT,
+	                                 g_param_spec_boolean ("no-stretch",
+	                                         NULL,
+	                                         NULL,
+	                                         FALSE,
+	                                         G_PARAM_READWRITE));
+}
+
+static void
+set_visual (GtkWidget *widget)
+{
+	GdkScreen *screen;
+	GdkVisual *visual;
+
+	screen = gtk_widget_get_screen (widget);
+	visual = gdk_screen_get_rgba_visual (screen);
+	if (visual == NULL)
+	{
+		visual = gdk_screen_get_system_visual (screen);
+	}
+
+	gtk_widget_set_visual (widget, visual);
+}
+
+static void
+gste_slideshow_init (GSTESlideshow *show)
+{
+	show->priv = gste_slideshow_get_instance_private (show);
+
+	show->priv->images_location = g_strdup (DEFAULT_IMAGES_LOCATION);
+
+	show->priv->op_q = g_async_queue_new ();
+	show->priv->results_q = g_async_queue_new ();
+
+	g_thread_new ("loadthread", (GThreadFunc)load_threadfunc, show->priv->op_q);
+
+	set_visual (GTK_WIDGET (show));
+}
+
+static void
+gste_slideshow_finalize (GObject *object)
+{
+	GSTESlideshow *show;
+	gpointer       result;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GSTE_IS_SLIDESHOW (object));
+
+	show = GSTE_SLIDESHOW (object);
+
+	g_return_if_fail (show->priv != NULL);
+
+	if (show->priv->surf)
+	{
+		cairo_surface_destroy (show->priv->surf);
+	}
+
+	if (show->priv->timeout_id > 0)
+	{
+		g_source_remove (show->priv->timeout_id);
+		show->priv->timeout_id = 0;
+	}
+
+	if (show->priv->results_pull_id > 0)
+	{
+		g_source_remove (show->priv->results_pull_id);
+		show->priv->results_pull_id = 0;
+	}
+
+	if (show->priv->results_q != NULL)
+	{
+		result = g_async_queue_try_pop (show->priv->results_q);
+
+		while (result)
+		{
+			result = g_async_queue_try_pop (show->priv->results_q);
+		}
+		g_async_queue_unref (show->priv->results_q);
+	}
+
+	g_free (show->priv->images_location);
+	show->priv->images_location = NULL;
+
+	if (show->priv->background_color)
+	{
+		g_slice_free (PangoColor, show->priv->background_color);
+		show->priv->background_color = NULL;
+	}
+
+	if (show->priv->timer != NULL)
+	{
+		g_timer_destroy (show->priv->timer);
+	}
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/5.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/5.html new file mode 100644 index 0000000..28219e0 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/5.html @@ -0,0 +1,1257 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
/* copy-theme-dialog.c
+ * Copyright (C) 2008 John Millikin <jmillikin@gmail.com>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+**/
+
+#include "config.h"
+
+#include <limits.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+#include "copy-theme-dialog.h"
+
+static void
+add_file_to_dialog (gpointer data, gpointer user_data);
+static void
+single_copy_complete (GObject *source_object, GAsyncResult *res,
+                      gpointer user_data);
+static void
+copy_theme_dialog_copy_next (CopyThemeDialog *dialog);
+static void
+copy_theme_dialog_cancel (CopyThemeDialog *dialog);
+static void
+copy_theme_dialog_finalize (GObject *obj);
+static void
+copy_theme_dialog_update_num_files (CopyThemeDialog *dlg);
+static void
+copy_theme_dialog_response (GtkDialog *dialog, gint response_id);
+static void
+eel_gtk_label_make_bold (GtkLabel *label);
+static void
+create_titled_label (GtkGrid    *grid,
+                     int         row,
+                     GtkWidget **title_widget,
+                     GtkWidget **label_text_widget);
+
+static GObjectClass *parent_class = NULL;
+
+enum
+{
+    CANCELLED = 0,
+    COMPLETE,
+    SIGNAL_COUNT
+};
+
+struct _CopyThemeDialogPrivate
+{
+	GtkWidget *progress;
+	GtkWidget *status;
+	GtkWidget *current;
+	GtkWidget *from;
+	GtkWidget *to;
+
+	GFile *theme_dir;
+	GSList *all_files, *file;
+	GSList *all_basenames, *basename;
+	guint index;
+	guint total_files;
+	GCancellable *cancellable;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (CopyThemeDialog, copy_theme_dialog, GTK_TYPE_DIALOG)<--- There is an unknown macro here somewhere. Configuration is required. If G_DEFINE_TYPE_WITH_PRIVATE is a macro then please configure it.
+
+guint signals[SIGNAL_COUNT] = {0, 0};
+
+static void
+copy_theme_dialog_class_init (CopyThemeDialogClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	klass->cancelled = copy_theme_dialog_cancel;
+	object_class->finalize = copy_theme_dialog_finalize;
+
+	GTK_DIALOG_CLASS (klass)->response = copy_theme_dialog_response;
+
+	signals[CANCELLED] = g_signal_new ("cancelled",
+	                                   G_TYPE_FROM_CLASS (object_class),
+	                                   G_SIGNAL_RUN_FIRST,
+	                                   G_STRUCT_OFFSET (CopyThemeDialogClass, cancelled),
+	                                   NULL, NULL,
+	                                   g_cclosure_marshal_VOID__VOID,
+	                                   G_TYPE_NONE, 0);
+
+	signals[COMPLETE] = g_signal_new ("complete",
+	                                  G_TYPE_FROM_CLASS (object_class),
+	                                  G_SIGNAL_RUN_LAST,
+	                                  G_STRUCT_OFFSET (CopyThemeDialogClass, complete),
+	                                  NULL, NULL,
+	                                  g_cclosure_marshal_VOID__VOID,
+	                                  G_TYPE_NONE, 0);
+
+	parent_class = g_type_class_peek_parent (klass);
+}
+
+GtkWidget*
+copy_theme_dialog_new (GList *files)
+{
+	GtkWidget *dialog;
+	CopyThemeDialogPrivate *priv;
+
+	dialog = GTK_WIDGET (g_object_new (COPY_THEME_DIALOG_TYPE, NULL));
+	priv = COPY_THEME_DIALOG (dialog)->priv;
+	priv->index = 0;
+	priv->total_files = 0;
+	priv->all_files = NULL;
+	priv->all_basenames = NULL;
+
+	g_list_foreach (files, add_file_to_dialog, dialog);
+
+	priv->file = priv->all_files;
+	priv->basename = priv->all_basenames;
+
+	return dialog;
+}
+
+static gboolean
+copy_finished (CopyThemeDialog *dialog)
+{
+	return (g_cancellable_is_cancelled (dialog->priv->cancellable) ||
+	        dialog->priv->file == NULL);
+}
+
+static void
+copy_theme_dialog_init (CopyThemeDialog *dlg)
+{
+	GtkWidget *vbox;
+	GtkWidget *hbox;
+	GtkWidget *progress_vbox;
+	GtkWidget *grid;
+	GtkWidget *label;
+	GtkWidget *dialog_vbox;
+	char      *markup;
+	gchar     *theme_dir_path;
+
+	dlg->priv = copy_theme_dialog_get_instance_private (dlg);
+
+	/* Find and, if needed, create the directory for storing themes */
+	theme_dir_path = g_build_filename (g_get_user_data_dir (),
+	                                   "applications", "screensavers",
+	                                   NULL);
+	dlg->priv->theme_dir = g_file_new_for_path (theme_dir_path);
+	g_mkdir_with_parents (theme_dir_path, S_IRWXU);
+	g_free (theme_dir_path);
+
+	/* For cancelling async I/O operations */
+	dlg->priv->cancellable = g_cancellable_new ();
+
+	/* GUI settings */
+	dialog_vbox = gtk_dialog_get_content_area (GTK_DIALOG (dlg));
+
+	gtk_container_set_border_width (GTK_CONTAINER (dialog_vbox),
+	                                4);
+	gtk_box_set_spacing (GTK_BOX (dialog_vbox), 4);
+
+	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+	gtk_box_pack_start (GTK_BOX (dialog_vbox), vbox, TRUE, TRUE, 0);
+
+	dlg->priv->status = gtk_label_new ("");
+	markup = g_strdup_printf ("<big><b>%s</b></big>", _("Copying files"));
+	gtk_label_set_markup (GTK_LABEL (dlg->priv->status), markup);
+	g_free (markup);
+
+	gtk_widget_set_halign (dlg->priv->status, GTK_ALIGN_START);
+	gtk_widget_set_valign (dlg->priv->status, GTK_ALIGN_START);
+	gtk_box_pack_start (GTK_BOX (vbox), dlg->priv->status, FALSE, FALSE, 0);
+
+	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+
+	grid = gtk_grid_new ();
+	gtk_grid_set_row_spacing (GTK_GRID (grid), 4);
+	gtk_grid_set_column_spacing (GTK_GRID (grid), 4);
+	gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
+
+	create_titled_label (GTK_GRID (grid), 0,
+	                     &label,
+	                     &dlg->priv->from);
+	gtk_label_set_text (GTK_LABEL (label), _("From:"));
+	create_titled_label (GTK_GRID (grid), 1,
+	                     &label,
+	                     &dlg->priv->to);
+	gtk_label_set_text (GTK_LABEL (label), _("To:"));
+
+	gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (grid), FALSE, FALSE, 0);
+
+	progress_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+	gtk_box_set_homogeneous (GTK_BOX (progress_vbox), TRUE);
+	gtk_box_pack_start (GTK_BOX (vbox), progress_vbox, FALSE, FALSE, 0);
+
+	dlg->priv->progress = gtk_progress_bar_new ();
+	gtk_box_pack_start (GTK_BOX (progress_vbox),
+	                    dlg->priv->progress, FALSE, FALSE, 0);
+
+	dlg->priv->current = gtk_label_new ("");
+	gtk_box_pack_start (GTK_BOX (progress_vbox),
+	                    dlg->priv->current, FALSE, FALSE, 0);
+	gtk_widget_set_halign (dlg->priv->current, GTK_ALIGN_START);
+
+	gtk_dialog_add_button (GTK_DIALOG (dlg),
+	                       "gtk-cancel", GTK_RESPONSE_CANCEL);
+
+	gtk_window_set_title (GTK_WINDOW (dlg),
+	                      _("Copying themes"));
+	gtk_container_set_border_width (GTK_CONTAINER (dlg), 6);
+
+	gtk_widget_show_all (dialog_vbox);
+}
+
+static void
+add_file_to_dialog (gpointer data, gpointer user_data)
+{
+	CopyThemeDialogPrivate *priv;
+	GFile *file;
+	gchar *basename = NULL, *raw_basename;
+
+	priv = COPY_THEME_DIALOG (user_data)->priv;
+	file = G_FILE (data);
+
+	raw_basename = g_file_get_basename (file);
+	if (g_str_has_suffix (raw_basename, ".desktop"))
+	{
+		/* FIXME: validate key file? */
+		basename = g_strndup (raw_basename,
+		                      /* 8 = strlen (".desktop") */
+		                      strlen (raw_basename) - 8);
+	}
+	g_free (raw_basename);
+
+	if (basename)
+	{
+		g_object_ref (file);
+		priv->all_files = g_slist_append (priv->all_files, file);
+		priv->all_basenames = g_slist_append (priv->all_basenames, basename);
+		priv->total_files++;
+	}
+
+	else
+	{
+		GtkWidget *dialog;
+		gchar *uri;
+
+		dialog = gtk_message_dialog_new (GTK_WINDOW (user_data),
+		                                 GTK_DIALOG_MODAL,
+		                                 GTK_MESSAGE_ERROR,
+		                                 GTK_BUTTONS_OK,
+		                                 _("Invalid screensaver theme"));
+		uri = g_file_get_uri (file);
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+		        _("%s does not appear to be a valid screensaver theme."),
+		        uri);
+		g_free (uri);
+		gtk_window_set_title (GTK_WINDOW (dialog), "");
+		gtk_window_set_icon_name (GTK_WINDOW (dialog), "preferences-desktop-screensaver");
+
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+	}
+}
+
+static void
+single_copy_complete (GObject *source_object, GAsyncResult *res,
+                      gpointer user_data)
+{
+	GError *error = NULL;
+	gboolean should_continue = FALSE;
+	CopyThemeDialog *dialog = COPY_THEME_DIALOG (user_data);
+
+	if (g_file_copy_finish (G_FILE (source_object), res, &error))
+	{
+		should_continue = TRUE;
+	}
+
+	else
+	{
+		/* If the file already exists, generate a new random name
+		 * and try again.
+		**/
+		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+		{
+			GFile *file, *destination;
+			gchar *basename, *full_basename;
+			g_error_free (error);
+
+			file = G_FILE (dialog->priv->file->data);
+			basename = (gchar *) (dialog->priv->basename->data);
+
+			g_return_if_fail (file != NULL);
+			g_return_if_fail (basename != NULL);
+
+			full_basename = g_strdup_printf ("%s-%u.desktop",
+			                                 basename,
+			                                 g_random_int ());
+			destination = g_file_get_child (dialog->priv->theme_dir,
+			                                full_basename);
+			g_free (full_basename);
+
+			g_file_copy_async (file, destination, G_FILE_COPY_NONE,
+			                   G_PRIORITY_DEFAULT,
+			                   dialog->priv->cancellable,
+			                   NULL, NULL,
+			                   single_copy_complete, dialog);
+		}
+
+		else
+		{
+			if (g_error_matches (error, G_IO_ERROR,
+			                     G_IO_ERROR_CANCELLED))
+			{
+				/* User has cancelled the theme copy */
+				g_signal_emit (G_OBJECT (dialog),
+				               signals[CANCELLED],
+				               0, NULL);
+			}
+
+			else
+			{
+				/* Some other error occurred, ignore and
+				 * try to copy remaining files
+				**/
+				should_continue = TRUE;
+			}
+
+			g_error_free (error);
+		}
+	}
+
+	/* Update informational widgets and, if needed, signal
+	 * copy completion.
+	**/
+	if (should_continue)
+	{
+		dialog->priv->index++;
+		dialog->priv->file = dialog->priv->file->next;
+		dialog->priv->basename = dialog->priv->basename->next;
+		copy_theme_dialog_update_num_files (dialog);
+		copy_theme_dialog_copy_next (dialog);
+	}
+}
+
+/* Try to copy the theme file to the user's screensaver directory.
+ * If a file with the given name already exists, the error will be
+ * caught later and the copy re-attempted with a random value
+ * appended to the filename.
+**/
+static void
+copy_theme_dialog_copy_next (CopyThemeDialog *dialog)
+{
+	GFile *file, *destination;
+	gchar *basename, *full_basename;
+
+	if (copy_finished (dialog))
+	{
+		g_signal_emit (G_OBJECT (dialog), signals[COMPLETE],
+		               0, NULL);
+		return;
+	}
+
+	file = G_FILE (dialog->priv->file->data);
+	basename = (gchar *) (dialog->priv->basename->data);
+
+	g_return_if_fail (file != NULL);
+	g_return_if_fail (basename != NULL);
+
+	full_basename = g_strdup_printf ("%s.desktop", basename);
+	destination = g_file_get_child (dialog->priv->theme_dir, full_basename);
+	g_free (full_basename);
+
+	g_file_copy_async (file, destination, G_FILE_COPY_NONE,
+	                   G_PRIORITY_DEFAULT, dialog->priv->cancellable,
+	                   NULL, NULL, single_copy_complete, dialog);
+}
+
+static gboolean
+timeout_display_dialog (gpointer data)
+{
+	if (IS_COPY_THEME_DIALOG (data))
+	{
+		CopyThemeDialog *dialog = COPY_THEME_DIALOG (data);
+		if (!copy_finished (dialog))
+		{
+			gtk_widget_show (GTK_WIDGET (dialog));
+
+			g_signal_connect (dialog, "response",
+			                  G_CALLBACK (copy_theme_dialog_response),
+			                  dialog);
+		}
+	}
+	return FALSE;
+}
+
+void
+copy_theme_dialog_begin (CopyThemeDialog *dialog)
+{
+	gtk_widget_hide (GTK_WIDGET (dialog));
+
+	/* If the copy operation takes more than half a second to
+	 * complete, display the dialog.
+	**/
+	g_timeout_add (500, timeout_display_dialog, dialog);
+
+	copy_theme_dialog_copy_next (dialog);
+}
+
+static void
+copy_theme_dialog_cancel (CopyThemeDialog *dialog)
+{
+	g_cancellable_cancel (dialog->priv->cancellable);
+}
+
+static void
+copy_theme_dialog_finalize (GObject *obj)
+{
+	CopyThemeDialog *dlg = COPY_THEME_DIALOG (obj);
+
+	g_object_unref (dlg->priv->theme_dir);
+	g_slist_free_full (dlg->priv->all_files, g_object_unref);
+	g_slist_free_full (dlg->priv->all_basenames, g_free);
+	g_object_unref (dlg->priv->cancellable);
+
+	if (parent_class->finalize)
+		parent_class->finalize (G_OBJECT (dlg));
+}
+
+static void
+copy_theme_dialog_update_num_files (CopyThemeDialog *dlg)
+{
+	gchar *str = g_strdup_printf (_("Copying file: %u of %u"),
+	                              dlg->priv->index, dlg->priv->total_files);
+	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (dlg->priv->progress), str);
+	g_free (str);
+}
+
+static void
+copy_theme_dialog_response (GtkDialog *dialog, gint response_id)
+{
+	g_cancellable_cancel (COPY_THEME_DIALOG (dialog)->priv->cancellable);
+}
+
+/**
+ * eel_gtk_label_make_bold.
+ *
+ * Switches the font of label to a bold equivalent.
+ * @label: The label.
+ **/
+static void
+eel_gtk_label_make_bold (GtkLabel *label)
+{
+	PangoFontDescription *font_desc;
+
+	font_desc = pango_font_description_new ();
+
+	pango_font_description_set_weight (font_desc,
+	                                   PANGO_WEIGHT_BOLD);
+
+	/* This will only affect the weight of the font, the rest is
+	 * from the current state of the widget, which comes from the
+	 * theme or user prefs, since the font desc only has the
+	 * weight flag turned on.
+	 */
+	gtk_widget_override_font (GTK_WIDGET (label), font_desc);
+	pango_font_description_free (font_desc);
+}
+
+/* from caja */
+static void
+create_titled_label (GtkGrid    *grid,
+                     int         row,
+                     GtkWidget **title_widget,
+                     GtkWidget **label_text_widget)
+{
+	*title_widget = gtk_label_new ("");
+	eel_gtk_label_make_bold (GTK_LABEL (*title_widget));
+	gtk_widget_set_halign (*title_widget, GTK_ALIGN_END);
+	gtk_widget_set_valign (*title_widget, GTK_ALIGN_START);
+
+	gtk_grid_attach (grid, *title_widget,
+	                 0, row, 1, 1);
+	gtk_widget_show (*title_widget);
+
+	*label_text_widget = gtk_label_new ("");
+	gtk_label_set_ellipsize (GTK_LABEL (*label_text_widget), PANGO_ELLIPSIZE_END);
+	gtk_widget_set_hexpand (*label_text_widget, TRUE);
+	gtk_grid_attach (grid, *label_text_widget,
+	                 1, row, 1, 1);
+	gtk_widget_show (*label_text_widget);
+	gtk_widget_set_halign (*label_text_widget, GTK_ALIGN_START);
+	gtk_widget_set_valign (*label_text_widget, GTK_ALIGN_START);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/6.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/6.html new file mode 100644 index 0000000..59b1819 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/6.html @@ -0,0 +1,445 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
/*
+ * gs-auth-bsdauth.c --- verifying typed passwords with bsd_auth(3)
+ *
+ * Copyright (c) 1993-1998 Jamie Zawinski <jwz@jwz.org>
+ * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (c) 2009 Antoine Jacoutot <ajacoutot@openbsd.org>
+ * Copyright (c) 2017 Robert Nagy <robert@openbsd.org>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <pwd.h>
+#include <sys/types.h>
+
+#include <login_cap.h>
+#include <bsd_auth.h>
+
+#include "gs-auth.h"
+#include "subprocs.h"
+
+static gboolean verbose_enabled = FALSE;
+
+GQuark
+gs_auth_error_quark (void)
+{
+	static GQuark quark = 0;
+	if (! quark) {
+		quark = g_quark_from_static_string ("gs_auth_error");
+	}
+
+	return quark;
+}
+
+void
+gs_auth_set_verbose (gboolean enabled)
+{
+	verbose_enabled = enabled;
+}
+
+gboolean
+gs_auth_get_verbose (void)
+{
+	return verbose_enabled;
+}
+
+gboolean
+gs_auth_verify_user (const char       *username,
+                     const char       *display,
+                     GSAuthMessageFunc func,
+                     gpointer          data,
+                     GError          **error)
+{
+	int res;
+	char *password;
+
+	/* ask for the password for user */
+	if (func != NULL) {
+		func (GS_AUTH_MESSAGE_PROMPT_ECHO_OFF,
+		    "Password: ",
+		    &password,
+		    data);
+	}
+
+	if (password == NULL) {<--- Uninitialized variable: password
+		return FALSE;
+	}
+
+	/* authenticate */
+	res = auth_userokay((char *)username, NULL, "auth-mate-screensaver", password);
+
+	return res;
+}
+
+gboolean
+gs_auth_init (void)
+{
+	return TRUE;
+}
+
+gboolean
+gs_auth_priv_init (void)
+{
+	return TRUE;
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/7.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/7.html new file mode 100644 index 0000000..150c40a --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/7.html @@ -0,0 +1,1857 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2006 Ray Strode <rstrode@redhat.com>
+ * Copyright (C) 2003 Bill Nottingham <notting@redhat.com>
+ * Copyright (c) 1993-2003 Jamie Zawinski <jwz@jwz.org>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <security/pam_appl.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "gs-auth.h"
+#include "gs-auth-pam.h"
+
+#include "subprocs.h"
+
+/* Some time between Red Hat 4.2 and 7.0, the words were transposed
+   in the various PAM_x_CRED macro names.  Yay!
+*/
+#ifndef  PAM_REFRESH_CRED
+# define PAM_REFRESH_CRED PAM_CRED_REFRESH
+#endif
+
+#ifdef HAVE_PAM_FAIL_DELAY
+/* We handle delays ourself.*/
+/* Don't set this to 0 (Linux bug workaround.) */
+# define PAM_NO_DELAY(pamh) pam_fail_delay ((pamh), 1)
+#else  /* !HAVE_PAM_FAIL_DELAY */
+# define PAM_NO_DELAY(pamh) /* */
+#endif /* !HAVE_PAM_FAIL_DELAY */
+
+/* On SunOS 5.6, and on Linux with PAM 0.64, pam_strerror() takes two args.
+   On some other Linux systems with some other version of PAM (e.g.,
+   whichever Debian release comes with a 2.2.5 kernel) it takes one arg.
+   I can't tell which is more "recent" or "correct" behavior, so configure
+   figures out which is in use for us.  Shoot me!
+*/
+#ifdef PAM_STRERROR_TWO_ARGS
+# define PAM_STRERROR(pamh, status) pam_strerror((pamh), (status))
+#else  /* !PAM_STRERROR_TWO_ARGS */
+# define PAM_STRERROR(pamh, status) pam_strerror((status))
+#endif /* !PAM_STRERROR_TWO_ARGS */
+
+static gboolean      verbose_enabled = FALSE;
+static pam_handle_t *pam_handle = NULL;
+static gboolean      did_we_ask_for_password = FALSE;
+
+struct pam_closure
+{
+	const char       *username;
+	GSAuthMessageFunc cb_func;
+	gpointer          cb_data;
+	int               signal_fd;
+	int               result;
+};
+
+typedef struct
+{
+	struct pam_closure *closure;
+	GSAuthMessageStyle style;
+	const char        *msg;
+	char             **resp;
+	gboolean           should_interrupt_stack;
+} GsAuthMessageHandlerData;
+
+static GCond  message_handled_condition;
+static GMutex message_handler_mutex;
+
+GQuark
+gs_auth_error_quark (void)
+{
+	static GQuark quark = 0;
+	if (! quark)
+	{
+		quark = g_quark_from_static_string ("gs_auth_error");
+	}
+
+	return quark;
+}
+
+void
+gs_auth_set_verbose (gboolean enabled)
+{
+	verbose_enabled = enabled;
+}
+
+gboolean
+gs_auth_get_verbose (void)
+{
+	return verbose_enabled;
+}
+
+static gboolean
+auth_message_handler (GSAuthMessageStyle style,
+                      const char        *msg,
+                      char             **response,
+                      gpointer           data)
+{
+	gboolean ret;
+
+	ret = TRUE;
+	*response = NULL;
+
+	switch (style)
+	{
+	case GS_AUTH_MESSAGE_PROMPT_ECHO_ON:
+		break;
+	case GS_AUTH_MESSAGE_PROMPT_ECHO_OFF:
+		if (msg != NULL && g_str_has_prefix (msg, _("Password:")))
+		{
+			did_we_ask_for_password = TRUE;
+		}
+		break;
+	case GS_AUTH_MESSAGE_ERROR_MSG:
+		break;
+	case GS_AUTH_MESSAGE_TEXT_INFO:
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+
+	return ret;
+}
+
+static gboolean
+gs_auth_queued_message_handler (gpointer user_data)
+{
+	GsAuthMessageHandlerData *data = user_data;
+	gboolean res;
+
+	if (gs_auth_get_verbose ())
+	{
+		g_message ("Waiting for lock");
+	}
+
+	g_mutex_lock (&message_handler_mutex);
+
+	if (gs_auth_get_verbose ())
+	{
+		g_message ("Waiting for response");
+	}
+
+	res = data->closure->cb_func (data->style,
+	                              data->msg,
+	                              data->resp,
+	                              data->closure->cb_data);
+
+	data->should_interrupt_stack = res == FALSE;
+
+	g_cond_signal (&message_handled_condition);
+	g_mutex_unlock (&message_handler_mutex);
+
+	if (gs_auth_get_verbose ())
+	{
+		g_message ("Got response");
+	}
+
+	return FALSE;
+}
+
+static gboolean
+gs_auth_run_message_handler (struct pam_closure *c,
+                             GSAuthMessageStyle  style,
+                             const char         *msg,
+                             char              **resp)
+{
+	GsAuthMessageHandlerData data;
+
+	data.closure = c;
+	data.style = style;
+	data.msg = msg;
+	data.resp = resp;
+	data.should_interrupt_stack = TRUE;
+
+	g_mutex_lock (&message_handler_mutex);
+
+	/* Queue the callback in the gui (the main) thread
+	 */
+	g_idle_add (gs_auth_queued_message_handler, &data);
+
+	if (gs_auth_get_verbose ())
+	{
+		g_message ("Waiting for respose to message style %d: '%s'", style, msg);
+	}
+
+	/* Wait for the response
+	 */
+	g_cond_wait (&message_handled_condition,
+	             &message_handler_mutex);
+	g_mutex_unlock (&message_handler_mutex);
+
+	if (gs_auth_get_verbose ())
+	{
+		g_message ("Got respose to message style %d: interrupt:%d", style, data.should_interrupt_stack);
+	}
+
+	return data.should_interrupt_stack == FALSE;
+}
+
+static int
+pam_conversation (int                        nmsgs,
+                  const struct pam_message **msg,
+                  struct pam_response      **resp,
+                  void                      *closure)
+{
+	int                  replies = 0;
+	struct pam_response *reply = NULL;
+	struct pam_closure  *c = (struct pam_closure *) closure;
+	gboolean             res;
+	int                  ret;
+
+	reply = (struct pam_response *) calloc (nmsgs, sizeof (*reply));
+
+	if (reply == NULL)
+	{
+		return PAM_CONV_ERR;
+	}
+
+	res = TRUE;<--- Variable 'res' is assigned a value that is never used.
+	ret = PAM_SUCCESS;
+
+	for (replies = 0; replies < nmsgs && ret == PAM_SUCCESS; replies++)
+	{
+		GSAuthMessageStyle style;
+		char              *utf8_msg;
+
+		style = pam_style_to_gs_style (msg [replies]->msg_style);
+
+		utf8_msg = g_locale_to_utf8 (msg [replies]->msg,
+		                             -1,
+		                             NULL,
+		                             NULL,
+		                             NULL);
+
+		/* if we couldn't convert text from locale then
+		 * assume utf-8 and hope for the best */
+		if (utf8_msg == NULL)
+		{
+			char *p;
+			char *q;
+
+			utf8_msg = g_strdup (msg [replies]->msg);
+
+			p = utf8_msg;
+			while (*p != '\0' && !g_utf8_validate ((const char *)p, -1, (const char **)&q))
+			{
+				*q = '?';
+				p = q + 1;
+			}
+		}
+
+		/* handle message locally first */
+		auth_message_handler (style,
+		                      utf8_msg,
+		                      &reply [replies].resp,
+		                      NULL);
+
+		if (c->cb_func != NULL)
+		{
+			if (gs_auth_get_verbose ())
+			{
+				g_message ("Handling message style %d: '%s'", style, utf8_msg);
+			}
+
+			/* blocks until the gui responds
+			 */
+			res = gs_auth_run_message_handler (c,
+			                                   style,
+			                                   utf8_msg,
+			                                   &reply [replies].resp);
+
+			if (gs_auth_get_verbose ())
+			{
+				g_message ("Msg handler returned %d", res);
+			}
+
+			/* If the handler returns FALSE - interrupt the PAM stack */
+			if (res)
+			{
+				reply [replies].resp_retcode = PAM_SUCCESS;
+			}
+			else
+			{
+				int i;
+				for (i = 0; i <= replies; i++)
+				{
+					free (reply [i].resp);
+				}
+				free (reply);
+				reply = NULL;
+				ret = PAM_CONV_ERR;
+			}
+		}
+
+		g_free (utf8_msg);
+	}
+
+	*resp = reply;
+
+	return ret;
+}
+
+static gboolean
+close_pam_handle (int status)
+{
+
+	if (pam_handle != NULL)
+	{
+		int status2;
+
+		status2 = pam_end (pam_handle, status);
+		pam_handle = NULL;
+
+		if (gs_auth_get_verbose ())
+		{
+			g_message (" pam_end (...) ==> %d (%s)",
+			           status2,
+			           (status2 == PAM_SUCCESS ? "Success" : "Failure"));
+		}
+	}
+
+	return TRUE;
+}
+
+static gboolean
+create_pam_handle (const char      *username,
+                   const char      *display,
+                   struct pam_conv *conv,
+                   int             *status_code)
+{
+	int         status;
+	const char *service = PAM_SERVICE_NAME;
+	char       *disp;
+	gboolean    ret;
+
+	if (pam_handle != NULL)
+	{
+		g_warning ("create_pam_handle: Stale pam handle around, cleaning up");
+		close_pam_handle (PAM_SUCCESS);
+	}
+
+	/* init things */
+	pam_handle = NULL;
+	status = -1;<--- status is assigned
+	disp = NULL;
+	ret = TRUE;<--- ret is assigned
+
+	/* Initialize a PAM session for the user */
+	if ((status = pam_start (service, username, conv, &pam_handle)) != PAM_SUCCESS)<--- status is overwritten
+	{
+		pam_handle = NULL;
+		g_warning (_("Unable to establish service %s: %s\n"),
+		           service,
+		           PAM_STRERROR (NULL, status));
+
+		if (status_code != NULL)
+		{
+			*status_code = status;
+		}
+
+		ret = FALSE;
+		goto out;
+	}
+
+	if (gs_auth_get_verbose ())
+	{
+		g_message ("pam_start (\"%s\", \"%s\", ...) ==> %d (%s)",
+		           service,
+		           username,
+		           status,
+		           PAM_STRERROR (pam_handle, status));
+	}
+
+	disp = g_strdup (display);
+	if (disp == NULL)
+	{
+		disp = g_strdup (":0.0");
+	}
+
+	if ((status = pam_set_item (pam_handle, PAM_TTY, disp)) != PAM_SUCCESS)
+	{
+		g_warning (_("Can't set PAM_TTY=%s"), display);
+
+		if (status_code != NULL)
+		{
+			*status_code = status;
+		}
+
+		ret = FALSE;
+		goto out;
+	}
+
+	ret = TRUE;<--- ret is overwritten
+	g_cond_init (&message_handled_condition);
+	g_mutex_init (&message_handler_mutex);
+
+out:
+	if (status_code != NULL)
+	{
+		*status_code = status;
+	}
+
+	g_free (disp);
+
+	return ret;
+}
+
+static void
+set_pam_error (GError **error,
+               int      status)
+{
+	if (status == PAM_AUTH_ERR || status == PAM_USER_UNKNOWN)
+	{
+		char *msg;
+
+		if (did_we_ask_for_password)
+		{
+			msg = g_strdup (_("Incorrect password."));
+		}
+		else
+		{
+			msg = g_strdup (_("Authentication failed."));
+		}
+
+		g_set_error (error,
+		             GS_AUTH_ERROR,
+		             GS_AUTH_ERROR_AUTH_ERROR,
+		             "%s",
+		             msg);
+		g_free (msg);
+	}
+	else if (status == PAM_PERM_DENIED)
+	{
+		g_set_error (error,
+		             GS_AUTH_ERROR,
+		             GS_AUTH_ERROR_AUTH_DENIED,
+		             "%s",
+		             _("Not permitted to gain access at this time."));
+	}
+	else if (status == PAM_ACCT_EXPIRED)
+	{
+		g_set_error (error,
+		             GS_AUTH_ERROR,
+		             GS_AUTH_ERROR_AUTH_DENIED,
+		             "%s",
+		             _("No longer permitted to access the system."));
+	}
+
+}
+
+static gpointer
+gs_auth_thread_func (gpointer data)
+{
+	int              auth_operation_fd;
+	static const int flags = 0;
+	int              status;
+	int              status2;
+	struct timespec  timeout;
+	sigset_t         set;
+	const void      *p;
+
+	auth_operation_fd = GPOINTER_TO_INT (data);
+
+	timeout.tv_sec = 0;
+	timeout.tv_nsec = 1;
+
+	set = block_sigchld ();
+
+	status = pam_authenticate (pam_handle, flags);
+
+	sigtimedwait (&set, NULL, &timeout);
+	unblock_sigchld ();
+
+	if (gs_auth_get_verbose ())
+	{
+		g_message ("   pam_authenticate (...) ==> %d (%s)",
+		           status,
+		           PAM_STRERROR (pam_handle, status));
+	}
+
+	if (status != PAM_SUCCESS)
+	{
+		goto done;
+	}
+
+	if ((status = pam_get_item (pam_handle, PAM_USER, &p)) != PAM_SUCCESS)
+	{
+		/* is not really an auth problem, but it will
+		   pretty much look as such, it shouldn't really
+		   happen */
+		goto done;
+	}
+
+	/* We don't actually care if the account modules fail or succeed,
+	 * but we need to run them anyway because certain pam modules
+	 * depend on side effects of the account modules getting run.
+	 */
+	status2 = pam_acct_mgmt (pam_handle, 0);
+
+	if (gs_auth_get_verbose ())
+	{
+		g_message ("pam_acct_mgmt (...) ==> %d (%s)\n",
+		           status2,
+		           PAM_STRERROR (pam_handle, status2));
+	}
+
+	/* FIXME: should we handle these? */
+	switch (status2)
+	{
+	case PAM_SUCCESS:
+		break;
+	case PAM_NEW_AUTHTOK_REQD:
+		break;
+	case PAM_AUTHINFO_UNAVAIL:
+		break;
+	case PAM_ACCT_EXPIRED:
+		break;
+	case PAM_PERM_DENIED:
+		break;
+	default :
+		break;
+	}
+
+	/* Each time we successfully authenticate, refresh credentials,
+	   for Kerberos/AFS/DCE/etc.  If this fails, just ignore that
+	   failure and blunder along; it shouldn't matter.
+
+	   Note: this used to be PAM_REFRESH_CRED instead of
+	   PAM_REINITIALIZE_CRED, but Jason Heiss <jheiss@ee.washington.edu>
+	   says that the Linux PAM library ignores that one, and only refreshes
+	   credentials when using PAM_REINITIALIZE_CRED.
+	*/
+	status2 = pam_setcred (pam_handle, PAM_REINITIALIZE_CRED);
+	if (gs_auth_get_verbose ())
+	{
+		g_message ("   pam_setcred (...) ==> %d (%s)",
+		           status2,
+		           PAM_STRERROR (pam_handle, status2));
+	}
+
+done:
+	/* we're done, close the fd and wake up the main
+	 * loop
+	 */
+	close (auth_operation_fd);
+
+	return GINT_TO_POINTER (status);
+}
+
+static gboolean
+gs_auth_loop_quit (GIOChannel  *source,
+                   GIOCondition condition,
+                   gboolean    *thread_done)
+{
+	*thread_done = TRUE;
+	gtk_main_quit ();
+	return TRUE; /* keep the event source */
+}
+
+static gboolean
+gs_auth_pam_verify_user (pam_handle_t *handle,
+                         int          *status)
+{
+	GThread    *auth_thread;
+	GIOChannel *channel;
+	guint       watch_id;
+	int         auth_operation_fds[2];
+	int         auth_status;
+	gboolean    thread_done;
+
+	channel = NULL;
+	watch_id = 0;
+	auth_status = PAM_AUTH_ERR;
+
+	/* This pipe gives us a set of fds we can hook into
+	 * the event loop to be notified when our helper thread
+	 * is ready to be reaped.
+	 */
+	if (pipe (auth_operation_fds) < 0)
+	{
+		goto out;
+	}
+
+	if (fcntl (auth_operation_fds[0], F_SETFD, FD_CLOEXEC) < 0)
+	{
+		close (auth_operation_fds[0]);
+		close (auth_operation_fds[1]);
+		goto out;
+	}
+
+	if (fcntl (auth_operation_fds[1], F_SETFD, FD_CLOEXEC) < 0)
+	{
+		close (auth_operation_fds[0]);
+		close (auth_operation_fds[1]);
+		goto out;
+	}
+
+	channel = g_io_channel_unix_new (auth_operation_fds[0]);
+
+	/* we use a recursive main loop to process ui events
+	 * while we wait on a thread to handle the blocking parts
+	 * of pam authentication.
+	 */
+	thread_done = FALSE;
+	watch_id = g_io_add_watch (channel, G_IO_ERR | G_IO_HUP,
+	                           (GIOFunc) gs_auth_loop_quit, &thread_done);
+
+	auth_thread = g_thread_new ("auththread",
+                                    gs_auth_thread_func,
+                                    GINT_TO_POINTER (auth_operation_fds[1]));
+
+	if (auth_thread == NULL)
+	{
+		goto out;
+	}
+
+	gtk_main ();
+
+	/* if the event loop was quit before the thread is done then we can't
+	 * reap the thread without blocking on it finishing.  The
+	 * thread may not ever finish though if the pam module is blocking.
+	 *
+	 * The only time the event loop is going to stop when the thread isn't
+	 * done, however, is if the dialog quits early (from, e.g., "cancel"),
+	 * so we can just exit.  An alternative option would be to switch to
+	 * using pthreads directly and calling pthread_cancel.
+	 */
+	if (!thread_done)
+	{
+		raise (SIGTERM);
+	}
+
+	auth_status = GPOINTER_TO_INT (g_thread_join (auth_thread));
+
+out:
+	if (watch_id != 0)
+	{
+		g_source_remove (watch_id);
+		watch_id = 0;
+	}
+
+	if (channel != NULL)
+	{
+		g_io_channel_unref (channel);
+	}
+
+	if (status)
+	{
+		*status = auth_status;
+	}
+
+	return auth_status == PAM_SUCCESS;
+}
+
+gboolean
+gs_auth_verify_user (const char       *username,
+                     const char       *display,
+                     GSAuthMessageFunc func,
+                     gpointer          data,
+                     GError          **error)
+{
+	int                status = -1;
+	struct pam_conv    conv;
+	struct pam_closure c;
+	struct passwd     *pwent;
+
+	pwent = getpwnam (username);
+	if (pwent == NULL)
+	{
+		return FALSE;
+	}
+
+	c.username = username;
+	c.cb_func = func;
+	c.cb_data = data;
+
+	conv.conv = &pam_conversation;
+	conv.appdata_ptr = (void *) &c;
+
+	/* Initialize PAM. */
+	create_pam_handle (username, display, &conv, &status);
+	if (status != PAM_SUCCESS)
+	{
+		goto done;
+	}
+
+	pam_set_item (pam_handle, PAM_USER_PROMPT, _("Username:"));
+
+	PAM_NO_DELAY(pam_handle);
+
+	did_we_ask_for_password = FALSE;
+	if (! gs_auth_pam_verify_user (pam_handle, &status))
+	{
+		goto done;
+	}
+
+done:
+	if (status != PAM_SUCCESS)
+	{
+		set_pam_error (error, status);
+	}
+
+	close_pam_handle (status);
+
+	return (status == PAM_SUCCESS ? TRUE : FALSE);
+}
+
+gboolean
+gs_auth_init (void)
+{
+	return TRUE;
+}
+
+gboolean
+gs_auth_priv_init (void)
+{
+	/* We have nothing to do at init-time.
+	   However, we might as well do some error checking.
+	   If "/etc/pam.d" exists and is a directory, but "/etc/pam.d/xlock"
+	   does not exist, warn that PAM probably isn't going to work.
+
+	   This is a priv-init instead of a non-priv init in case the directory
+	   is unreadable or something (don't know if that actually happens.)
+	*/
+	const char   dir [] = "/etc/pam.d";
+	const char  file [] = "/etc/pam.d/" PAM_SERVICE_NAME;
+	const char file2 [] = "/etc/pam.conf";
+	struct stat st;
+
+	if (g_stat (dir, &st) == 0 && st.st_mode & S_IFDIR)
+	{
+		if (g_stat (file, &st) != 0)
+		{
+			g_warning ("%s does not exist.\n"
+			           "Authentication via PAM is unlikely to work.",
+			           file);
+		}
+	}
+	else if (g_stat (file2, &st) == 0)
+	{
+		FILE *f = g_fopen (file2, "r");
+		if (f)
+		{
+			gboolean ok = FALSE;
+			char buf[255];
+			while (fgets (buf, sizeof(buf), f))
+			{
+				if (strstr (buf, PAM_SERVICE_NAME))
+				{
+					ok = TRUE;
+					break;
+				}
+			}
+
+			fclose (f);
+			if (!ok)
+			{
+				g_warning ("%s does not list the `%s' service.\n"
+				           "Authentication via PAM is unlikely to work.",
+				           file2, PAM_SERVICE_NAME);
+			}
+		}
+		/* else warn about file2 existing but being unreadable? */
+	}
+	else
+	{
+		g_warning ("Neither %s nor %s exist.\n"
+		           "Authentication via PAM is unlikely to work.",
+		           file2, file);
+	}
+
+	/* Return true anyway, just in case. */
+	return TRUE;
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/8.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/8.html new file mode 100644 index 0000000..c62abb5 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/8.html @@ -0,0 +1,577 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "gs-debug.h"
+
+static gboolean debugging = FALSE;
+static FILE    *debug_out = NULL;
+
+/* Based on rhythmbox/lib/rb-debug.c */
+/* Our own funky debugging function, should only be used when something
+ * is not going wrong, if something *is* wrong use g_warning.
+ */
+void
+gs_debug_real (const char *func,
+               const char *file,
+               const int   line,
+               const char *format, ...)
+{
+	va_list args;
+	char    buffer [1025];
+	char   *str_time;
+	time_t  the_time;
+
+	if (debugging == FALSE)
+		return;
+
+	va_start (args, format);
+
+	g_vsnprintf (buffer, 1024, format, args);
+
+	va_end (args);
+
+	time (&the_time);
+	str_time = g_new0 (char, 255);
+	strftime (str_time, 254, "%H:%M:%S", localtime (&the_time));
+
+	fprintf ((debug_out ? debug_out : stderr),
+	         "[%s] %s:%d (%s):\t %s\n",
+	         func, file, line, str_time, buffer);
+
+	if (debug_out)
+		fflush (debug_out);
+
+	g_free (str_time);
+}
+
+gboolean
+gs_debug_enabled (void)
+{
+	return debugging;
+}
+
+void
+gs_debug_init (gboolean debug,
+               gboolean to_file)
+{
+	/* return if already initialized */
+	if (debugging == TRUE)
+	{
+		return;
+	}
+
+	debugging = debug;
+
+	if (debug && to_file)
+	{
+		const char path [50] = "mate_screensaver_debug_XXXXXX";
+		int        fd;
+
+		fd = g_file_open_tmp (path, NULL, NULL);
+
+		if (fd >= 0)
+		{
+			debug_out = fdopen (fd, "a");
+		}
+	}
+
+	gs_debug ("Debugging %s", (debug) ? "enabled" : "disabled");
+}
+
+void
+gs_debug_shutdown (void)
+{
+	if (! debugging)
+		return;
+
+	gs_debug ("Shutting down debugging");
+
+	debugging = FALSE;
+
+	if (debug_out != NULL)
+	{
+		fclose (debug_out);
+		debug_out = NULL;
+	}
+}
+
+void
+_gs_profile_log (const char *func,
+                 const char *note,
+                 const char *format,
+                 ...)
+{
+	va_list args;
+	char   *str;
+	char   *formatted;
+
+	if (format == NULL)
+	{
+		formatted = g_strdup ("");
+	}
+	else
+	{
+		va_start (args, format);
+		formatted = g_strdup_vprintf (format, args);
+		va_end (args);
+	}
+
+	if (func != NULL)
+	{
+		str = g_strdup_printf ("MARK: %s %s: %s %s", g_get_prgname(), func, note ? note : "", formatted);
+	}
+	else
+	{
+		str = g_strdup_printf ("MARK: %s: %s %s", g_get_prgname(), note ? note : "", formatted);
+	}
+
+	g_free (formatted);
+
+	g_access (str, F_OK);
+	g_free (str);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/9.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/9.html new file mode 100644 index 0000000..54fe131 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/9.html @@ -0,0 +1,2105 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2009 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2009      Red Hat, Inc.
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include "gs-fade.h"
+#include "gs-debug.h"
+
+#define MATE_DESKTOP_USE_UNSTABLE_API
+
+#include "libmate-desktop/mate-rr.h"
+
+/* XFree86 4.x+ Gamma fading */
+
+#ifdef HAVE_XF86VMODE_GAMMA
+
+#include <X11/extensions/xf86vmode.h>
+
+#define XF86_MIN_GAMMA  0.1
+
+#endif /* HAVE_XF86VMODE_GAMMA */
+
+static void     gs_fade_finalize   (GObject        *object);
+
+struct GSGammaInfo
+{
+	int              size;
+	unsigned short  *r;
+	unsigned short  *g;
+	unsigned short  *b;
+};
+
+struct GSFadeScreenPrivate
+{
+	int                 fade_type;
+	int                 num_ramps;
+	/* one per crtc in randr mode */
+	struct GSGammaInfo *info;
+	/* one per screen in theory */
+	MateRRScreen      *rrscreen;
+#ifdef HAVE_XF86VMODE_GAMMA
+	/* one per screen also */
+	XF86VidModeGamma    vmg;
+#endif /* HAVE_XF86VMODE_GAMMA */
+	gboolean (*fade_setup)           (GSFade *fade);
+	gboolean (*fade_set_alpha_gamma) (GSFade *fade,
+	                                  gdouble alpha);
+	void     (*fade_finish)          (GSFade *fade);
+};
+
+struct GSFadePrivate
+{
+	guint            enabled : 1;
+	guint            active : 1;
+
+	guint            timeout;
+
+	guint            step;
+	guint            num_steps;
+	guint            timer_id;
+
+	gdouble          alpha_per_iter;
+	gdouble          current_alpha;
+
+	struct GSFadeScreenPrivate screen_priv;
+};
+
+enum
+{
+    FADED,
+    LAST_SIGNAL
+};
+
+enum
+{
+    FADE_TYPE_NONE,
+    FADE_TYPE_GAMMA_NUMBER,
+    FADE_TYPE_GAMMA_RAMP,
+    FADE_TYPE_XRANDR,
+};
+
+static guint         signals [LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSFade, gs_fade, G_TYPE_OBJECT)
+
+static gpointer fade_object = NULL;
+
+#ifdef HAVE_XF86VMODE_GAMMA
+
+/* This is needed because the VidMode extension doesn't work
+   on remote displays -- but if the remote display has the extension
+   at all, XF86VidModeQueryExtension returns true, and then
+   XF86VidModeQueryVersion dies with an X error.
+*/
+
+static gboolean error_handler_hit = FALSE;
+
+static int
+ignore_all_errors_ehandler (Display     *dpy,
+                            XErrorEvent *error)
+{
+	error_handler_hit = TRUE;
+
+	return 0;
+}
+
+static Bool
+safe_XF86VidModeQueryVersion (Display *dpy,
+                              int     *majP,
+                              int     *minP)
+{
+	Bool          result;
+	XErrorHandler old_handler;
+
+	XSync (dpy, False);
+	error_handler_hit = FALSE;
+	old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
+
+	result = XF86VidModeQueryVersion (dpy, majP, minP);
+
+	XSync (dpy, False);
+	XSetErrorHandler (old_handler);
+	XSync (dpy, False);
+
+	return (error_handler_hit
+	        ? False
+	        : result);
+}
+
+static gboolean
+xf86_whack_gamma (int              screen,
+                  struct GSFadeScreenPrivate *screen_priv,
+                  float            ratio)
+{
+	Bool status;
+	struct GSGammaInfo *gamma_info;
+	GdkDisplay *display;
+
+	gamma_info = screen_priv->info;
+
+	if (!gamma_info)
+		return FALSE;
+
+	if (ratio < 0)
+	{
+		ratio = 0;
+	}
+	if (ratio > 1)
+	{
+		ratio = 1;
+	}
+
+	if (gamma_info->size == 0)
+	{
+		/* we only have a gamma number, not a ramp. */
+
+		XF86VidModeGamma g2;
+
+		g2.red   = screen_priv->vmg.red   * ratio;
+		g2.green = screen_priv->vmg.green * ratio;
+		g2.blue  = screen_priv->vmg.blue  * ratio;
+
+		if (g2.red < XF86_MIN_GAMMA)
+		{
+			g2.red = XF86_MIN_GAMMA;
+		}
+		if (g2.green < XF86_MIN_GAMMA)
+		{
+			g2.green = XF86_MIN_GAMMA;
+		}
+		if (g2.blue < XF86_MIN_GAMMA)
+		{
+			g2.blue = XF86_MIN_GAMMA;
+		}
+
+		status = XF86VidModeSetGamma (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), screen, &g2);
+	}
+	else
+	{
+
+# ifdef HAVE_XF86VMODE_GAMMA_RAMP
+		unsigned short *r, *g, *b;
+		int i;
+
+		r = g_new0 (unsigned short, gamma_info->size);
+		g = g_new0 (unsigned short, gamma_info->size);
+		b = g_new0 (unsigned short, gamma_info->size);
+
+		for (i = 0; i < gamma_info->size; i++)
+		{
+			r[i] = (unsigned short) (ratio * (float) gamma_info->r[i]);
+			g[i] = (unsigned short) (ratio * (float) gamma_info->g[i]);
+			b[i] = (unsigned short) (ratio * (float) gamma_info->b[i]);
+		}
+
+		status = XF86VidModeSetGammaRamp (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), screen, gamma_info->size, r, g, b);
+
+		g_free (r);
+		g_free (g);
+		g_free (b);
+
+# else  /* !HAVE_XF86VMODE_GAMMA_RAMP */
+		abort ();
+# endif /* !HAVE_XF86VMODE_GAMMA_RAMP */
+	}
+
+	display = gdk_display_get_default ();
+	gdk_display_flush (display);
+
+	return status;
+}
+
+#endif /* HAVE_XF86VMODE_GAMMA */
+
+/* VidModeExtension version 2.0 or better is needed to do gamma.
+   2.0 added gamma values; 2.1 added gamma ramps.
+*/
+# define XF86_VIDMODE_GAMMA_MIN_MAJOR 2
+# define XF86_VIDMODE_GAMMA_MIN_MINOR 0
+# define XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR 2
+# define XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR 1
+
+gboolean
+gs_fade_get_enabled (GSFade *fade)
+{
+	g_return_val_if_fail (GS_IS_FADE (fade), FALSE);
+
+	return fade->priv->enabled;
+}
+
+void
+gs_fade_set_enabled (GSFade  *fade,
+                     gboolean enabled)
+{
+	g_return_if_fail (GS_IS_FADE (fade));
+
+	if (fade->priv->enabled != enabled)
+	{
+		fade->priv->enabled = (enabled != FALSE);
+	}
+}
+
+#ifdef HAVE_XF86VMODE_GAMMA
+static gboolean
+gamma_fade_setup (GSFade *fade)
+{
+	gboolean         res;
+	struct GSFadeScreenPrivate *screen_priv;
+
+	screen_priv = &fade->priv->screen_priv;
+
+	if (screen_priv->info)
+		return TRUE;
+
+# ifndef HAVE_XF86VMODE_GAMMA_RAMP
+	if (FADE_TYPE_GAMMA_RAMP == screen_priv->fade_type)
+	{
+		/* server is newer than client! */
+		screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
+	}
+# endif
+
+# ifdef HAVE_XF86VMODE_GAMMA_RAMP
+
+	screen_priv->info = g_new0(struct GSGammaInfo, 1);
+	screen_priv->num_ramps = 1;
+
+	if (FADE_TYPE_GAMMA_RAMP == screen_priv->fade_type)
+	{
+		/* have ramps */
+
+		res = XF86VidModeGetGammaRampSize (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+		                                   GDK_SCREEN_XNUMBER (gdk_screen_get_default ()),
+		                                   &screen_priv->info->size);
+		if (!res || screen_priv->info->size <= 0)
+		{
+			screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
+			goto test_number;
+		}
+
+		screen_priv->info->r = g_new0 (unsigned short, screen_priv->info->size);
+		screen_priv->info->g = g_new0 (unsigned short, screen_priv->info->size);
+		screen_priv->info->b = g_new0 (unsigned short, screen_priv->info->size);
+
+		if (! (screen_priv->info->r && screen_priv->info->g && screen_priv->info->b))
+		{
+			screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
+			goto test_number;
+		}
+
+		res = XF86VidModeGetGammaRamp (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+		                               GDK_SCREEN_XNUMBER (gdk_screen_get_default ()),
+		                               screen_priv->info->size,
+		                               screen_priv->info->r,
+		                               screen_priv->info->g,
+		                               screen_priv->info->b);
+		if (! res)
+		{
+			screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
+			goto test_number;
+		}
+		gs_debug ("Initialized gamma ramp fade");
+	}
+# endif /* HAVE_XF86VMODE_GAMMA_RAMP */
+
+test_number:<--- Label 'test_number' is not used.
+	if (FADE_TYPE_GAMMA_NUMBER == screen_priv->fade_type)
+	{
+		/* only have gamma parameter, not ramps. */
+
+		res = XF86VidModeGetGamma (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+		                           GDK_SCREEN_XNUMBER (gdk_screen_get_default ()),
+		                           &screen_priv->vmg);
+		if (! res)
+		{
+			screen_priv->fade_type = FADE_TYPE_NONE;
+			goto test_none;
+		}
+		gs_debug ("Initialized gamma fade: %f %f %f",
+		          screen_priv->vmg.red,
+		          screen_priv->vmg.green,
+		          screen_priv->vmg.blue);
+	}
+
+test_none:
+	if (FADE_TYPE_NONE == screen_priv->fade_type)
+	{
+		goto FAIL;
+	}
+
+	return TRUE;
+FAIL:
+
+	return FALSE;
+}
+#endif /* HAVE_XF86VMODE_GAMMA */
+
+static void
+screen_fade_finish (GSFade *fade)
+{
+	struct GSFadeScreenPrivate *screen_priv;
+	int i;
+	screen_priv = &fade->priv->screen_priv;
+
+	if (!screen_priv->info)
+		return;
+
+	for (i = 0; i < screen_priv->num_ramps; i++)
+	{
+		if (screen_priv->info[i].r)
+			g_free (screen_priv->info[i].r);
+		if (screen_priv->info[i].g)
+			g_free (screen_priv->info[i].g);
+		if (screen_priv->info[i].b)
+			g_free (screen_priv->info[i].b);
+	}
+
+	g_free (screen_priv->info);
+	screen_priv->info = NULL;
+	screen_priv->num_ramps = 0;
+}
+
+#ifdef HAVE_XF86VMODE_GAMMA
+static gboolean
+gamma_fade_set_alpha_gamma (GSFade *fade,
+                            gdouble alpha)
+{
+	struct GSFadeScreenPrivate *screen_priv;
+	int screen_idx = GDK_SCREEN_XNUMBER (gdk_screen_get_default ());
+
+	screen_priv = &fade->priv->screen_priv;
+	xf86_whack_gamma (screen_idx, screen_priv, alpha);
+
+	return TRUE;
+}
+#endif /* HAVE_XF86VMODE_GAMMA */
+
+static void
+check_gamma_extension (GSFade *fade)
+{
+	struct GSFadeScreenPrivate *screen_priv;
+#ifdef HAVE_XF86VMODE_GAMMA
+	int      event;
+	int      error;
+	int      major;
+	int      minor;
+	gboolean res;
+#endif /* HAVE_XF86VMODE_GAMMA */
+
+	screen_priv = &fade->priv->screen_priv;
+
+#ifdef HAVE_XF86VMODE_GAMMA
+	res = XF86VidModeQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &event, &error);
+	if (! res)
+		goto fade_none;
+
+	res = safe_XF86VidModeQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor);
+	if (! res)
+		goto fade_none;
+
+	if (major < XF86_VIDMODE_GAMMA_MIN_MAJOR ||
+	        (major == XF86_VIDMODE_GAMMA_MIN_MAJOR &&
+	         minor < XF86_VIDMODE_GAMMA_MIN_MINOR))
+		goto fade_none;
+
+	screen_priv->fade_setup = gamma_fade_setup;
+	screen_priv->fade_finish = screen_fade_finish;
+	screen_priv->fade_set_alpha_gamma = gamma_fade_set_alpha_gamma;
+
+	if (major < XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR ||
+	        (major == XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR &&
+	         minor < XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR))
+	{
+		screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
+		return;
+	}
+
+	/* Copacetic */
+	screen_priv->fade_type = FADE_TYPE_GAMMA_RAMP;
+	return;
+fade_none:
+#endif
+	screen_priv->fade_type = FADE_TYPE_NONE;
+}
+
+/* Xrandr support */
+
+static gboolean xrandr_fade_setup (GSFade *fade)
+{
+	struct GSFadeScreenPrivate *screen_priv;
+	MateRRCrtc *crtc;
+	MateRRCrtc **crtcs;
+	int crtc_count = 0;
+	struct GSGammaInfo *info;
+	gboolean res;
+
+	screen_priv = &fade->priv->screen_priv;
+
+	if (screen_priv->info)
+		return TRUE;
+
+	/* refresh the screen info */
+	mate_rr_screen_refresh (screen_priv->rrscreen, NULL);
+
+	crtcs = mate_rr_screen_list_crtcs (screen_priv->rrscreen);
+	while (*crtcs)
+	{
+		crtc_count++;
+		crtcs++;
+	};
+
+	screen_priv->info = g_new0 (struct GSGammaInfo, crtc_count);
+	screen_priv->num_ramps = crtc_count;
+
+	crtc_count = 0;
+	crtcs = mate_rr_screen_list_crtcs (screen_priv->rrscreen);
+	while (*crtcs)
+	{
+		crtc = *crtcs;
+
+		info = &screen_priv->info[crtc_count];
+
+		/* if no mode ignore crtc */
+		if (!mate_rr_crtc_get_current_mode (crtc))
+		{
+			info->size = 0;
+			info->r = NULL;
+			info->g = NULL;
+			info->b = NULL;
+		}
+		else
+		{
+			res = mate_rr_crtc_get_gamma (crtc, &info->size,
+			                              &info->r, &info->g,
+			                              &info->b);
+			if (res == FALSE)
+				goto fail;
+		}
+
+		crtcs++;
+		crtc_count++;
+	}
+	return TRUE;
+fail:
+	return FALSE;
+}
+
+static void xrandr_crtc_whack_gamma (MateRRCrtc *crtc,
+                                     struct GSGammaInfo *gamma_info,
+                                     float            ratio)
+{
+	unsigned short *r, *g, *b;
+	int i;
+
+	if (gamma_info->size == 0)
+		return;
+
+	if (ratio < 0)
+	{
+		ratio = 0;
+	}
+	if (ratio > 1)
+	{
+		ratio = 1;
+	}
+
+	r = g_new0 (unsigned short, gamma_info->size);
+	g = g_new0 (unsigned short, gamma_info->size);
+	b = g_new0 (unsigned short, gamma_info->size);
+
+	for (i = 0; i < gamma_info->size; i++)
+	{
+		r[i] = (unsigned short) (ratio * (float) gamma_info->r[i]);
+		g[i] = (unsigned short) (ratio * (float) gamma_info->g[i]);
+		b[i] = (unsigned short) (ratio * (float) gamma_info->b[i]);
+	}
+
+	mate_rr_crtc_set_gamma (crtc, gamma_info->size,
+	                        r, g, b);
+	g_free (r);
+	g_free (g);
+	g_free (b);
+}
+
+static gboolean xrandr_fade_set_alpha_gamma (GSFade *fade,
+        gdouble alpha)
+{
+	struct GSFadeScreenPrivate *screen_priv;
+	struct GSGammaInfo *info;
+	MateRRCrtc **crtcs;
+	int i;
+
+	screen_priv = &fade->priv->screen_priv;
+
+	if (!screen_priv->info)
+		return FALSE;
+
+	crtcs = mate_rr_screen_list_crtcs (screen_priv->rrscreen);
+	i = 0;
+
+	while (*crtcs)
+	{
+		info = &screen_priv->info[i];
+		xrandr_crtc_whack_gamma (*crtcs, info, alpha);
+		i++;
+		crtcs++;
+	}
+	return TRUE;
+}
+
+static void
+check_randr_extension (GSFade *fade)
+{
+	GdkDisplay *display = gdk_display_get_default ();
+	GdkScreen *screen = gdk_display_get_default_screen (display);
+	struct GSFadeScreenPrivate *screen_priv;
+
+	screen_priv = &fade->priv->screen_priv;
+
+	screen_priv->rrscreen = mate_rr_screen_new (screen,
+	                        NULL);
+	if (!screen_priv->rrscreen)
+	{
+		screen_priv->fade_type = FADE_TYPE_NONE;
+		return;
+	}
+
+	screen_priv->fade_type = FADE_TYPE_XRANDR;
+	screen_priv->fade_setup = xrandr_fade_setup;
+	screen_priv->fade_finish = screen_fade_finish;
+	screen_priv->fade_set_alpha_gamma = xrandr_fade_set_alpha_gamma;
+}
+
+static gboolean
+gs_fade_set_alpha (GSFade *fade,
+                   gdouble alpha)
+{
+	gboolean ret = FALSE;
+
+	switch (fade->priv->screen_priv.fade_type)
+	{
+	case FADE_TYPE_GAMMA_RAMP:
+	case FADE_TYPE_GAMMA_NUMBER:
+	case FADE_TYPE_XRANDR:
+		ret = fade->priv->screen_priv.fade_set_alpha_gamma (fade, alpha);
+		break;
+	case FADE_TYPE_NONE:
+		ret = FALSE;
+		break;
+	default:
+		g_warning ("Unknown fade type");
+		ret = FALSE;
+		break;
+	}
+
+	return ret;
+}
+
+static gboolean
+gs_fade_out_iter (GSFade *fade)
+{
+	gboolean ret;
+
+	if (fade->priv->current_alpha < 0.01)
+	{
+		return FALSE;
+	}
+
+	fade->priv->current_alpha -= fade->priv->alpha_per_iter;
+
+	ret = gs_fade_set_alpha (fade, fade->priv->current_alpha);
+
+	return ret;
+}
+
+static gboolean
+gs_fade_stop (GSFade *fade)
+{
+	if (fade->priv->timer_id != 0)
+	{
+		g_source_remove (fade->priv->timer_id);
+		fade->priv->timer_id = 0;
+	}
+
+	fade->priv->step = 0;
+	fade->priv->active = FALSE;
+
+	return TRUE;
+}
+
+void
+gs_fade_finish (GSFade *fade)
+{
+	g_return_if_fail (GS_IS_FADE (fade));
+
+	if (! fade->priv->active)
+	{
+		return;
+	}
+
+	gs_fade_stop (fade);
+
+	g_signal_emit (fade, signals [FADED], 0);
+
+	fade->priv->active = FALSE;
+}
+
+static gboolean
+fade_out_timer (GSFade *fade)
+{
+	gboolean res;
+
+	res = gs_fade_out_iter (fade);
+
+	/* if failed then fade is complete */
+	if (! res)
+	{
+		gs_fade_finish (fade);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+gboolean
+gs_fade_get_active (GSFade *fade)
+{
+	g_return_val_if_fail (GS_IS_FADE (fade), FALSE);
+
+	return fade->priv->active;
+}
+
+static void
+gs_fade_set_timeout (GSFade   *fade,
+                     guint     timeout)
+{
+	g_return_if_fail (GS_IS_FADE (fade));
+
+	fade->priv->timeout = timeout;
+}
+
+static void
+gs_fade_start (GSFade *fade,
+               guint   timeout)
+{
+	g_return_if_fail (GS_IS_FADE (fade));
+
+	if ((fade->priv->screen_priv.fade_type != FADE_TYPE_NONE) &&
+	    (fade->priv->screen_priv.fade_setup (fade) == FALSE))
+		return;
+
+	if (fade->priv->timer_id != 0)
+		gs_fade_stop (fade);
+
+	fade->priv->active = TRUE;
+	gs_fade_set_timeout (fade, timeout);
+
+	if (fade->priv->screen_priv.fade_type != FADE_TYPE_NONE)
+	{
+		double steps_per_sec = 60.0;
+		double msecs_per_step = 1000.0 / steps_per_sec;
+		double num_steps = ((double) fade->priv->timeout) / msecs_per_step;
+
+		fade->priv->alpha_per_iter = 1.0 / num_steps;
+		fade->priv->timer_id = g_timeout_add ((guint) msecs_per_step,
+		                                      (GSourceFunc) fade_out_timer,
+		                                      fade);
+	}
+	else
+	{
+		gs_fade_finish (fade);
+	}
+}
+
+typedef struct
+{
+	GSFadeDoneFunc done_cb;
+	gpointer       data;
+} FadedCallbackData;
+
+static void
+gs_fade_async_callback (GSFade            *fade,
+                        FadedCallbackData *cdata)
+{
+	g_signal_handlers_disconnect_by_func (fade,
+	                                      gs_fade_async_callback,
+	                                      cdata);
+
+	if (cdata->done_cb)
+	{
+		cdata->done_cb (fade, cdata->data);
+	}
+
+	g_free (cdata);
+}
+
+void
+gs_fade_async (GSFade        *fade,
+               guint          timeout,
+               GSFadeDoneFunc func,
+               gpointer       data)
+{
+	g_return_if_fail (GS_IS_FADE (fade));
+
+	/* if fade is active then pause it */
+	if (fade->priv->active)
+	{
+		gs_fade_stop (fade);
+	}
+
+	if (func)
+	{
+		FadedCallbackData *cb_data;
+
+		cb_data = g_new0 (FadedCallbackData, 1);
+		cb_data->done_cb = func;
+		cb_data->data = data;
+
+		g_signal_connect (fade, "faded",
+		                  G_CALLBACK (gs_fade_async_callback),
+		                  cb_data);
+	}
+
+	gs_fade_start (fade, timeout);
+}
+
+static void
+gs_fade_sync_callback (GSFade *fade,
+                       int    *flag)
+{
+	*flag = TRUE;
+	g_signal_handlers_disconnect_by_func (fade,
+	                                      gs_fade_sync_callback,
+	                                      flag);
+}
+
+void
+gs_fade_sync (GSFade        *fade,
+              guint          timeout)
+{
+	int      flag = FALSE;
+
+	g_return_if_fail (GS_IS_FADE (fade));
+
+	/* if fade is active then pause it */
+	if (fade->priv->active)
+	{
+		gs_fade_stop (fade);
+	}
+
+	g_signal_connect (fade, "faded",
+	                  G_CALLBACK (gs_fade_sync_callback),
+	                  &flag);
+
+	gs_fade_start (fade, timeout);
+
+	while (! flag)
+	{
+		gtk_main_iteration ();
+	}
+}
+
+void
+gs_fade_reset (GSFade *fade)
+{
+	g_return_if_fail (GS_IS_FADE (fade));
+
+	gs_debug ("Resetting fade");
+
+	if (fade->priv->active)
+	{
+		gs_fade_stop (fade);
+	}
+
+	fade->priv->current_alpha = 1.0;
+
+	gs_fade_set_alpha (fade, fade->priv->current_alpha);
+
+	if (fade->priv->screen_priv.fade_type != FADE_TYPE_NONE)
+		fade->priv->screen_priv.fade_finish (fade);
+}
+
+static void
+gs_fade_class_init (GSFadeClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = gs_fade_finalize;
+
+	signals [FADED] =
+	    g_signal_new ("faded",
+	                  G_TYPE_FROM_CLASS (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  G_STRUCT_OFFSET (GSFadeClass, faded),
+	                  NULL,
+	                  NULL,
+	                  g_cclosure_marshal_VOID__VOID,
+	                  G_TYPE_NONE,
+	                  0, G_TYPE_NONE);
+}
+
+static void
+gs_fade_init (GSFade *fade)
+{
+	fade->priv = gs_fade_get_instance_private (fade);
+
+	fade->priv->timeout = 1000;
+	fade->priv->current_alpha = 1.0;
+
+	check_randr_extension (fade);
+	if (!fade->priv->screen_priv.fade_type)
+		check_gamma_extension (fade);
+	gs_debug ("Fade type: %d", fade->priv->screen_priv.fade_type);
+}
+
+static void
+gs_fade_finalize (GObject *object)
+{
+	GSFade *fade;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GS_IS_FADE (object));
+
+	fade = GS_FADE (object);
+
+	g_return_if_fail (fade->priv != NULL);
+
+	fade->priv->screen_priv.fade_finish(fade);
+
+	if (fade->priv->screen_priv.rrscreen)
+		g_object_unref (fade->priv->screen_priv.rrscreen);
+	fade->priv->screen_priv.rrscreen = NULL;
+
+	G_OBJECT_CLASS (gs_fade_parent_class)->finalize (object);
+}
+
+GSFade *
+gs_fade_new (void)
+{
+	if (fade_object)
+	{
+		g_object_ref (fade_object);
+	}
+	else
+	{
+		fade_object = g_object_new (GS_TYPE_FADE, NULL);
+		g_object_add_weak_pointer (fade_object,
+		                           (gpointer *) &fade_object);
+	}
+
+	return GS_FADE (fade_object);
+}
+
+
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/index.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/index.html new file mode 100644 index 0000000..ad4e090 --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/index.html @@ -0,0 +1,297 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeinformationCppcheck cannot find all the include files (use --check-config for details)
helper/helper_proto.c
38variableScope398styleThe scope of the variable 'rd' can be reduced.
45arithOperationsOnVoidPointer467portability'buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
96knownConditionTrueFalse571styleCondition 'rd>0' is always true
110variableScope398styleThe scope of the variable 'wt' can be reduced.
117arithOperationsOnVoidPointer467portability'buf' is of type 'const void *'. When using void pointers in calculations, the behaviour is undefined.
helper/pam-helper.c
223shadowVariable398styleLocal variable 'program_name' shadows outer variable
241unreadVariable563styleVariable 'program_name' is assigned a value that is never used.
243unreadVariable563styleVariable 'program_name' is assigned a value that is never used.
savers/floaters.c
321constParameter398styleParameter 'position' can be declared with const
savers/gste-popsquares.c
232unreadVariable563styleVariable 'wanted' is assigned a value that is never used.
savers/gste-slideshow.c
91unknownMacroerrorThere is an unknown macro here somewhere. Configuration is required. If G_DEFINE_TYPE_WITH_PRIVATE is a macro then please configure it.
src/copy-theme-dialog.c
83unknownMacroerrorThere is an unknown macro here somewhere. Configuration is required. If G_DEFINE_TYPE_WITH_PRIVATE is a macro then please configure it.
src/gs-auth-bsdauth.c
84uninitvar457errorUninitialized variable: password
src/gs-auth-pam.c
255unreadVariable563styleVariable 'res' is assigned a value that is never used.
385redundantAssignment563styleVariable 'status' is reassigned a value before the old one has been used.
429redundantAssignment563styleVariable 'ret' is reassigned a value before the old one has been used.
src/gs-debug.c
136variableScope398styleThe scope of the variable 'args' can be reduced.
src/gs-fade.c
342unusedLabel398styleLabel 'test_number' is not used.
565variableScope398styleThe scope of the variable 'info' can be reduced.
src/gs-job.c
245ConfigurationNotCheckedinformationSkipping configuration 'HAVE_SETPRIORITY;PRIO_PROCESS' since the value of 'PRIO_PROCESS' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly.
src/gs-listener-dbus.c
150unknownMacroerrorThere is an unknown macro here somewhere. Configuration is required. If G_DEFINE_TYPE_WITH_PRIVATE is a macro then please configure it.
src/gs-lock-plug.c
609shadowFunction398styleLocal variable 'delete_handler' shadows outer function
981variableScope398styleThe scope of the variable 'icon_size' can be reduced.
src/gs-manager.c
1576unreadVariable563styleVariable 'n_monitors' is assigned a value that is never used.
1600constParameter398styleParameter 'monitor' can be declared with const
1606unreadVariable563styleVariable 'n_monitors' is assigned a value that is never used.
src/gs-theme-manager.c
63ConfigurationNotCheckedinformationSkipping configuration 'XSCREENSAVER_HACK_DIR' since the value of 'XSCREENSAVER_HACK_DIR' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly.
src/gs-watcher-x11.c
601redundantAssignment563styleVariable 'desired_server_interval' is reassigned a value before the old one has been used.
606redundantAssignment563styleVariable 'desired_allow_exp' is reassigned a value before the old one has been used.
614redundantAssignment563styleVariable 'desired_server_timeout' is reassigned a value before the old one has been used.
618knownConditionTrueFalse570styleCondition 'desired_prefer_blank!=current_prefer_blank' is always false
src/gs-window-x11.c
149variableScope398styleThe scope of the variable 'display' can be reduced.
789variableScope398styleThe scope of the variable 'events' can be reduced.
867variableScope398styleThe scope of the variable 'secondary_markup' can be reduced.
869variableScope398styleThe scope of the variable 'secondary_label' can be reduced.
1026unreadVariable563styleVariable 'finished' is assigned a value that is never used.
1129unreadVariable563styleVariable 'id' is assigned a value that is never used.
1362unreadVariable563styleVariable 'finished' is assigned a value that is never used.
1630unreadVariable563styleVariable 'finished' is assigned a value that is never used.
src/mate-screensaver-command.c
290memleakOnRealloc401errorCommon realloc mistake: 'buffer' nulled but not freed upon failure
312memleakOnRealloc401errorCommon realloc mistake: 'buffer' nulled but not freed upon failure
src/mate-screensaver-preferences-resources.c
9unusedStructMember563styleunion member 'Anonymous0::alignment' is never used.
9unusedStructMember563styleunion member 'Anonymous0::ptr' is never used.
src/mate-screensaver-preferences.c
1318unreadVariable563styleVariable 'suid' is assigned a value that is never used.
1319unreadVariable563styleVariable 'sgid' is assigned a value that is never used.
1320unreadVariable563styleVariable 'euid' is assigned a value that is never used.
1321unreadVariable563styleVariable 'egid' is assigned a value that is never used.
src/test-fade.c
92knownConditionTrueFalse570styleCondition 'error' is always false
+
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/stats.html b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/stats.html new file mode 100644 index 0000000..a1becbd --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/stats.html @@ -0,0 +1,190 @@ + + + + + + Cppcheck - HTML report - mate-screensaver + + + + + +
+ + + +
+

Top 10 files for error severity, total findings: 6
+   2  src/mate-screensaver-command.c
+   1  src/gs-listener-dbus.c
+   1  src/gs-auth-bsdauth.c
+   1  src/copy-theme-dialog.c
+   1  savers/gste-slideshow.c
+

+

Top 10 files for portability severity, total findings: 2
+   2  helper/helper_proto.c
+

+

Top 10 files for style severity, total findings: 38
+   8  src/gs-window-x11.c
+   4  src/mate-screensaver-preferences.c
+   4  src/gs-watcher-x11.c
+   3  src/gs-manager.c
+   3  src/gs-auth-pam.c
+   3  helper/pam-helper.c
+   3  helper/helper_proto.c
+   2  src/mate-screensaver-preferences-resources.c
+   2  src/gs-lock-plug.c
+   2  src/gs-fade.c
+

+

Top 10 files for information severity, total findings: 2
+   1  src/gs-theme-manager.c
+   1  src/gs-job.c
+

+ +
+ +
+ + diff --git a/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/style.css b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/style.css new file mode 100644 index 0000000..3897bfa --- /dev/null +++ b/2022-07-29-120110-6977-cppcheck@ae17179be38e_fix-20220729/style.css @@ -0,0 +1,177 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + height: 100%; + margin: 0; +} + +#wrapper { + position: fixed; + height: 100vh; + width: 100vw; + display: grid; + grid-template-rows: fit-content(8rem) auto fit-content(8rem); + grid-template-columns: fit-content(25%) 1fr; + grid-template-areas: + "header header" + "menu content" + "footer footer"; +} + +h1 { + margin: 0 0 8px -2px; + font-size: 175%; +} + +.header { + padding: 0 0 5px 15px; + grid-area: header; + border-bottom: thin solid #aaa; +} + +.footer { + grid-area: footer; + border-top: thin solid #aaa; + font-size: 85%; + +} + +.footer > p { + margin: 4px; +} + +#menu, +#menu_index { + grid-area: menu; + text-align: left; + overflow: auto; + padding: 0 23px 15px 15px; + border-right: thin solid #aaa; + min-width: 200px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; +} + +#content, +#content_index { + grid-area: content; + padding: 0px 5px 15px 15px; + overflow: auto; +} + +label { + white-space: nowrap; +} + +label.checkBtn.disabled { + color: #606060; + background: #e0e0e0; + font-style: italic; +} + +label.checkBtn, input[type="text"] { + border: 1px solid grey; + border-radius: 4px; + box-shadow: 1px 1px inset; + padding: 1px 5px; +} + +label.checkBtn { + white-space: nowrap; + background: #ccddff; +} + +label.unchecked { + background: #eff8ff; + box-shadow: 1px 1px 1px; +} + +label.checkBtn:hover, label.unchecked:hover{ + box-shadow: 0 0 2px; +} + +label.disabled:hover { + box-shadow: 1px 1px inset; +} + +label.checkBtn > input { + display:none; +} + +.summaryTable { + width: 100%; +} + +table.summaryTable td { padding: 0 5px 0 5px; } + +.statHeader, .severityHeader { + font-weight: bold; +} + +.warning { + background-color: #ffffa7; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.id-filtered, .severity-filtered, .file-filtered, .tool-filtered, .text-filtered { + visibility: collapse; +} -- cgit v1.2.1