1 /* wmshutdown - dockapp to shutdown or reboot your machine
3 * Copyright 2001, 2002 Rafael V. Aroca <rafael@linuxqos.cjb.net>
4 * Copyright 2014 Doug Torrance <dtorrance@piedmont.edu>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
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/>. */
22 #include "wmshutdown.xpm"
32 GTK_RESPONSE_HIBERNATE
35 #define HALT_METHOD "PowerOff"
36 #define REBOOT_METHOD "Reboot"
37 #define SUSPEND_METHOD "Suspend"
38 #define HIBERNATE_METHOD "Hibernate"
39 #define DBUS_PATH "/org/freedesktop/login1"
40 #define DBUS_INTERFACE "org.freedesktop.login1.Manager"
41 #define DBUS_DESTINATION "org.freedesktop.login1"
43 static int showVersion
;
44 static gboolean show_suspend
= FALSE
;
45 static gboolean show_hibernate
= FALSE
;
47 GtkWidget
*dialog
= NULL
;
49 static GOptionEntry entries
[] = {
50 { "version", 'v', 0, G_OPTION_ARG_NONE
, &showVersion
,
51 "Display version information", NULL
},
52 { "suspend", 's', 0, G_OPTION_ARG_NONE
, &show_suspend
,
53 "Show 'suspend' button", NULL
},
54 { "hibernate", 'b', 0, G_OPTION_ARG_NONE
, &show_hibernate
,
55 "Show 'hibernate' button", NULL
},
59 /* gtk3 dockapp code based on wmpasman by Brad Jorsch
60 * <anomie@users.sourceforge.net>
61 * http://sourceforge.net/projects/wmpasman */
63 GtkWidget
*cria_dock(GtkWidget
*mw
, unsigned int s
)
68 Window mainwin
, iw
, w
, p
, dummy1
, *dummy2
;
73 display
= gdk_display_get_default();
74 foobox
= gtk_window_new(GTK_WINDOW_POPUP
);
76 gtk_window_set_wmclass(GTK_WINDOW(mw
), g_get_prgname(), "DockApp");
77 gtk_widget_set_size_request(foobox
, 47, 47);
79 gtk_widget_realize(mw
);
80 gtk_widget_realize(foobox
);
82 d
= GDK_DISPLAY_XDISPLAY(display
);
83 mainwin
= GDK_WINDOW_XID(gtk_widget_get_window(mw
));
84 iw
= GDK_WINDOW_XID(gtk_widget_get_window(foobox
));
85 XQueryTree(d
, mainwin
, &dummy1
, &p
, &dummy2
, &dummy3
);
88 w
= XCreateSimpleWindow(d
, p
, 0, 0, 1, 1, 0, 0, 0);
89 XReparentWindow(d
, mainwin
, w
, 0, 0);
91 gtk_widget_show(foobox
);
92 wmHints
= XGetWMHints(d
, mainwin
);
94 wmHints
= XAllocWMHints();
95 wmHints
->flags
|= IconWindowHint
;
96 wmHints
->icon_window
= iw
;
97 XSetWMHints(d
, mainwin
, wmHints
);
99 XReparentWindow(d
, mainwin
, p
, 0, 0);
100 XDestroyWindow(d
, w
);
107 gtk_widget_destroy(dialog
);
111 void handle_click(GtkWidget
*widget
, gpointer data
)
113 GDBusConnection
*connection
;
114 GDBusMessage
*message
, *reply
;
115 GError
*error
= NULL
;
117 gchar
*method
= (gchar
*)data
;
119 connection
= g_bus_get_sync(G_BUS_TYPE_SYSTEM
, NULL
, &error
);
120 message
= g_dbus_message_new_method_call(
125 g_dbus_message_set_body(message
, g_variant_new("(b)", TRUE
));
126 g_dbus_message_set_destination(message
, DBUS_DESTINATION
);
127 reply
= g_dbus_connection_send_message_with_reply_sync(
128 connection
, message
, 0, -1, NULL
, NULL
, &error
);
130 if (g_dbus_message_get_message_type(reply
) ==
131 G_DBUS_MESSAGE_TYPE_ERROR
) {
134 dialog
= gtk_message_dialog_new(
135 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
136 GTK_DIALOG_DESTROY_WITH_PARENT
,
140 g_strcompress(g_variant_print(
141 g_dbus_message_get_body(reply
),
143 gtk_dialog_run(GTK_DIALOG(dialog
));
144 gtk_widget_destroy(dialog
);
147 g_object_unref(message
);
148 g_object_unref(reply
);
149 g_object_unref(connection
);
152 void button_press(GtkWidget
*widget
, GdkEvent
*event
)
155 GtkWidget
*halt_button
;
156 GtkWidget
*reboot_button
;
157 GtkWidget
*suspend_button
;
158 GtkWidget
*hibernate_button
;
159 GtkWidget
*cancel_button
;
160 GdkEventButton
*bevent
;
164 bevent
= (GdkEventButton
*)event
;
165 switch (bevent
->button
) {
169 dialog
= gtk_dialog_new();
170 label
= gtk_label_new("Shutdown confirmation");
171 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(
172 GTK_DIALOG(dialog
))),
175 gtk_dialog_add_buttons(GTK_DIALOG(dialog
),
176 "Halt", GTK_RESPONSE_HALT
,
177 "Reboot", GTK_RESPONSE_REBOOT
, NULL
);
178 halt_button
= gtk_dialog_get_widget_for_response(
181 reboot_button
= gtk_dialog_get_widget_for_response(
183 GTK_RESPONSE_REBOOT
);
184 g_signal_connect(halt_button
,
186 G_CALLBACK(handle_click
),
188 g_signal_connect(reboot_button
,
190 G_CALLBACK(handle_click
),
194 gtk_dialog_add_buttons(GTK_DIALOG(dialog
), "Suspend",
195 GTK_RESPONSE_SUSPEND
, NULL
);
197 gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog
),
198 GTK_RESPONSE_SUSPEND
);
199 g_signal_connect(suspend_button
,
201 G_CALLBACK(handle_click
),
204 if (show_hibernate
) {
205 gtk_dialog_add_buttons(GTK_DIALOG(dialog
), "Hibernate",
206 GTK_RESPONSE_HIBERNATE
, NULL
);
208 gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog
),
209 GTK_RESPONSE_HIBERNATE
);
210 g_signal_connect(hibernate_button
,
212 G_CALLBACK(handle_click
),
216 gtk_dialog_add_buttons(GTK_DIALOG(dialog
), "Cancel",
217 GTK_RESPONSE_CANCEL
, NULL
);
218 cancel_button
= gtk_dialog_get_widget_for_response(
220 GTK_RESPONSE_CANCEL
);
221 g_signal_connect(cancel_button
,
226 g_signal_connect(dialog
, "destroy", G_CALLBACK(fecha
), NULL
);
227 gtk_widget_show_all(dialog
);
234 int main(int argc
, char *argv
[])
236 GError
*error
= NULL
;
237 GOptionContext
*context
;
243 gtk_init(&argc
, &argv
);
245 context
= g_option_context_new(
246 "- dockapp to shutdown or reboot your machine");
247 g_option_context_add_main_entries(context
, entries
, NULL
);
248 g_option_context_add_group(context
, gtk_get_option_group(TRUE
));
249 g_option_context_parse(context
, &argc
, &argv
, &error
);
252 printf(PACKAGE_STRING
"\n");
256 gtkiw
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
257 dockArea
= cria_dock(gtkiw
, 47);
259 pixbuf
= gdk_pixbuf_new_from_xpm_data(image_name
);
260 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
261 gtk_widget_show(pixmap
);
262 gtk_container_add(GTK_CONTAINER(dockArea
), pixmap
);
264 gtk_widget_add_events(dockArea
, GDK_BUTTON_PRESS_MASK
);
265 g_signal_connect(dockArea
, "button-press-event",
266 G_CALLBACK(button_press
), NULL
);