1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail    : see the 'copyright' file.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include <string.h>
21 
22 #include "applet-struct.h"
23 #include "applet-logout.h"
24 #include "applet-reboot-required.h"
25 
26 static gboolean s_bRebootRequired = FALSE;
27 static gboolean s_bMonitored = FALSE;
28 
_get_default_message(void)29 static const gchar * _get_default_message (void)
30 {
31 	if (myConfig.cDefaultLabel) // has another default name
32 		return myConfig.cDefaultLabel;
33 	else
34 		return myApplet->pModule->pVisitCard->cTitle;
35 }
36 
_get_reboot_message(void)37 static gchar * _get_reboot_message (void)
38 {
39 	gchar *cMessage = NULL;
40 	gsize length = 0;
41 	g_file_get_contents (CD_REBOOT_NEEDED_FILE,
42 		&cMessage,
43 		&length,
44 		NULL);
45 	if (cMessage != NULL)
46 	{
47 		int len = strlen (cMessage);
48 		if (cMessage[len-1] == '\n')
49 			cMessage[len-1] = '\0';
50 	}
51 
52 	return (cMessage);
53 }
54 
_notify_action_required(void)55 static void _notify_action_required (void)
56 {
57 	CD_APPLET_DEMANDS_ATTENTION ("pulse", 20);
58 	gldi_dialogs_remove_on_icon (myIcon);
59 
60 	// it's not a good idea to reboot the computer before the end of the update ;)
61 	gchar *cName = g_strdup_printf ("%s\n%s", myIcon->cName,
62 		D_("Please do that at the end of the update."));
63 
64 	gldi_dialog_show_temporary_with_icon (cName, myIcon, myContainer, 15e3, "same icon");
65 
66 	g_free (cName);
67 
68 	gint iIconSize = MAX (myIcon->image.iWidth, myIcon->image.iHeight);
69 	gchar *cImagePath = cd_logout_check_icon (myConfig.cEmblemPath,
70 		(myConfig.iRebootNeededImage == CD_DISPLAY_EMBLEM ?
71 				iIconSize / 2 :
72 				iIconSize));
73 	if (! cImagePath)
74 	{
75 		cImagePath = cd_logout_check_icon (GLDI_ICON_NAME_REFRESH,
76 			(myConfig.iRebootNeededImage == CD_DISPLAY_EMBLEM ?
77 				iIconSize / 2 :
78 				iIconSize));
79 		if (! cImagePath)
80 			cImagePath = g_strdup (MY_APPLET_SHARE_DATA_DIR"/system-restart.svg");
81 	}
82 
83 	if (myConfig.iRebootNeededImage == CD_DISPLAY_EMBLEM)
84 		CD_APPLET_PRINT_OVERLAY_ON_MY_ICON (cImagePath, CAIRO_OVERLAY_UPPER_RIGHT);
85 	else
86 		CD_APPLET_SET_IMAGE_ON_MY_ICON (cImagePath);
87 	g_free (cImagePath);
88 }
89 
_stop_notify_action_required(void)90 static void _stop_notify_action_required (void)
91 {
92 	 // should not happen... mainly for the tests.
93 	gldi_dialogs_remove_on_icon (myIcon);
94 	if (myConfig.iRebootNeededImage == CD_DISPLAY_EMBLEM)
95 		CD_APPLET_PRINT_OVERLAY_ON_MY_ICON (NULL, CAIRO_OVERLAY_UPPER_RIGHT);
96 	else
97 		CD_APPLET_SET_IMAGE_ON_MY_ICON (myConfig.cDefaultIcon);
98 	CD_APPLET_STOP_DEMANDING_ATTENTION;
99 }
100 
_notify_reboot_requiered(gpointer pData)101 static gboolean _notify_reboot_requiered (gpointer pData)
102 {
103 	if (! myApplet || ! s_bRebootRequired)
104 	{
105 		s_bMonitored = FALSE;
106 		return FALSE;
107 	}
108 
109 	CairoDockFMEventType iEventType = GPOINTER_TO_INT (pData);
110 
111 	gchar *cMessage = _get_reboot_message ();
112 	if (cMessage && *cMessage != '\0')
113 		CD_APPLET_SET_NAME_FOR_MY_ICON (cMessage);
114 	else
115 		CD_APPLET_SET_NAME_FOR_MY_ICON (_get_default_message ());
116 	if (iEventType == CAIRO_DOCK_FILE_CREATED)
117 		_notify_action_required ();
118 
119 	g_free (cMessage);
120 	s_bMonitored = FALSE;
121 
122 	return FALSE;
123 }
124 
cd_logout_check_reboot_required(CairoDockFMEventType iEventType,const gchar * cURI)125 void cd_logout_check_reboot_required (CairoDockFMEventType iEventType, const gchar *cURI)
126 {
127 	switch (iEventType)
128 	{
129 		case CAIRO_DOCK_FILE_MODIFIED: // new message
130 		case CAIRO_DOCK_FILE_CREATED:  // reboot required
131 			s_bRebootRequired = TRUE;
132 			if (! s_bMonitored)
133 			{
134 				s_bMonitored = TRUE;
135 				gpointer pEventType = GINT_TO_POINTER (iEventType);
136 				#ifdef END_INSTALLATION_PID
137 				cairo_dock_fm_monitor_pid (END_INSTALLATION_PID, FALSE,
138 					_notify_reboot_requiered, TRUE, pEventType);
139 				#else
140 				_notify_reboot_requiered (pEventType);
141 				#endif
142 			}
143 		break;
144 
145 		case CAIRO_DOCK_FILE_DELETED:  // reboot/logout no more required (shouldn't happen)
146 			s_bRebootRequired = FALSE;
147 			_stop_notify_action_required (); // default icon
148 			CD_APPLET_SET_NAME_FOR_MY_ICON (_get_default_message ());
149 		break;
150 		default:
151 		break;
152 	}
153 }
154 
cd_logout_check_reboot_required_init(void)155 void cd_logout_check_reboot_required_init (void)
156 {
157 	if (g_file_test (CD_REBOOT_NEEDED_FILE, G_FILE_TEST_EXISTS))
158 	{
159 		cd_logout_check_reboot_required (CAIRO_DOCK_FILE_CREATED, CD_REBOOT_NEEDED_FILE);
160 	}
161 }
162 
cd_logout_can_safety_shutdown(void)163 gboolean cd_logout_can_safety_shutdown (void)
164 {
165 	gboolean bResult = ! s_bMonitored || ! s_bRebootRequired;
166 	#ifdef END_INSTALLATION_PID
167 	bResult &= cairo_dock_fm_get_pid (END_INSTALLATION_PID) == -1;
168 	#endif
169 	return bResult;
170 }