drop support for win32/osx and checkupdate plugin
that plugin has never been built in linux anyway due to logic in configure.ac
This commit is contained in:
@@ -1,18 +1,7 @@
|
||||
if OS_WIN32
|
||||
platform_sources = eggsmclient-win32.c
|
||||
platform_logout_test_ldflags = -mwindows
|
||||
else
|
||||
if OS_OSX
|
||||
platform_defines = -xobjective-c
|
||||
platform_ldflags = -framework Carbon
|
||||
platform_sources = eggsmclient-osx.c
|
||||
else
|
||||
platform_defines = -DEGG_SM_CLIENT_BACKEND_XSMP
|
||||
platform_libs = libeggdesktopfile.la
|
||||
platform_ltlibraries = libeggdesktopfile.la
|
||||
platform_sources = eggsmclient-xsmp.c
|
||||
endif
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DG_LOG_DOMAIN=\""EggSMClient"\" \
|
||||
@@ -45,8 +34,6 @@ libeggdesktopfile_la_SOURCES = \
|
||||
eggdesktopfile.h
|
||||
|
||||
EXTRA_DIST = \
|
||||
eggsmclient-osx.c \
|
||||
eggsmclient-win32.c \
|
||||
eggsmclient-xsmp.c
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Novell, Inc.
|
||||
* Copyright (C) 2008 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* EggSMClientOSX
|
||||
*
|
||||
* For details on the OS X logout process, see:
|
||||
* http://developer.apple.com/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/BootProcess.html#//apple_ref/doc/uid/20002130-114618
|
||||
*
|
||||
* EggSMClientOSX registers for the kAEQuitApplication AppleEvent; the
|
||||
* handler we register (quit_requested()) will be invoked from inside
|
||||
* the quartz event-handling code (specifically, from inside
|
||||
* [NSApplication nextEventMatchingMask]) when an AppleEvent arrives.
|
||||
* We use AESuspendTheCurrentEvent() and AEResumeTheCurrentEvent() to
|
||||
* allow asynchronous / non-main-loop-reentering processing of the
|
||||
* quit request. (These are part of the Carbon framework; it doesn't
|
||||
* seem to be possible to handle AppleEvents asynchronously from
|
||||
* Cocoa.)
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "eggsmclient-private.h"
|
||||
#include <glib.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
#define EGG_TYPE_SM_CLIENT_OSX (egg_sm_client_osx_get_type ())
|
||||
#define EGG_SM_CLIENT_OSX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_OSX, EggSMClientOSX))
|
||||
#define EGG_SM_CLIENT_OSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_OSX, EggSMClientOSXClass))
|
||||
#define EGG_IS_SM_CLIENT_OSX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_OSX))
|
||||
#define EGG_IS_SM_CLIENT_OSX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_OSX))
|
||||
#define EGG_SM_CLIENT_OSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_OSX, EggSMClientOSXClass))
|
||||
|
||||
typedef struct _EggSMClientOSX EggSMClientOSX;
|
||||
typedef struct _EggSMClientOSXClass EggSMClientOSXClass;
|
||||
|
||||
struct _EggSMClientOSX {
|
||||
EggSMClient parent;
|
||||
|
||||
AppleEvent quit_event, quit_reply;
|
||||
gboolean quit_requested, quitting;
|
||||
};
|
||||
|
||||
struct _EggSMClientOSXClass
|
||||
{
|
||||
EggSMClientClass parent_class;
|
||||
|
||||
};
|
||||
|
||||
static void sm_client_osx_startup (EggSMClient *client,
|
||||
const char *client_id);
|
||||
static void sm_client_osx_will_quit (EggSMClient *client,
|
||||
gboolean will_quit);
|
||||
static gboolean sm_client_osx_end_session (EggSMClient *client,
|
||||
EggSMClientEndStyle style,
|
||||
gboolean request_confirmation);
|
||||
|
||||
static pascal OSErr quit_requested (const AppleEvent *, AppleEvent *, long);
|
||||
|
||||
G_DEFINE_TYPE (EggSMClientOSX, egg_sm_client_osx, EGG_TYPE_SM_CLIENT)
|
||||
|
||||
static void
|
||||
egg_sm_client_osx_init (EggSMClientOSX *osx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_sm_client_osx_class_init (EggSMClientOSXClass *klass)
|
||||
{
|
||||
EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
|
||||
|
||||
sm_client_class->startup = sm_client_osx_startup;
|
||||
sm_client_class->will_quit = sm_client_osx_will_quit;
|
||||
sm_client_class->end_session = sm_client_osx_end_session;
|
||||
}
|
||||
|
||||
EggSMClient *
|
||||
egg_sm_client_osx_new (void)
|
||||
{
|
||||
return g_object_new (EGG_TYPE_SM_CLIENT_OSX, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
sm_client_osx_startup (EggSMClient *client,
|
||||
const char *client_id)
|
||||
{
|
||||
AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
|
||||
NewAEEventHandlerUPP (quit_requested),
|
||||
(long)GPOINTER_TO_SIZE (client), false);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_quit_requested (gpointer client)
|
||||
{
|
||||
egg_sm_client_quit_requested (client);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static pascal OSErr
|
||||
quit_requested (const AppleEvent *aevt, AppleEvent *reply, long refcon)
|
||||
{
|
||||
EggSMClient *client = GSIZE_TO_POINTER ((gsize)refcon);
|
||||
EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon);
|
||||
|
||||
g_return_val_if_fail (!osx->quit_requested, userCanceledErr);
|
||||
|
||||
/* FIXME AEInteractWithUser? */
|
||||
|
||||
osx->quit_requested = TRUE;
|
||||
AEDuplicateDesc (aevt, &osx->quit_event);
|
||||
AEDuplicateDesc (reply, &osx->quit_reply);
|
||||
AESuspendTheCurrentEvent (aevt);
|
||||
|
||||
/* Don't emit the "quit_requested" signal immediately, since we're
|
||||
* called from a weird point in the guts of gdkeventloop-quartz.c
|
||||
*/
|
||||
g_idle_add (idle_quit_requested, client);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static pascal OSErr
|
||||
quit_requested_resumed (const AppleEvent *aevt, AppleEvent *reply, long refcon)
|
||||
{
|
||||
EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon);
|
||||
|
||||
osx->quit_requested = FALSE;
|
||||
return osx->quitting ? noErr : userCanceledErr;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_will_quit (gpointer client)
|
||||
{
|
||||
EggSMClientOSX *osx = (EggSMClientOSX *)client;
|
||||
|
||||
/* Resume the event with a new handler that will return a value to
|
||||
* the system.
|
||||
*/
|
||||
AEResumeTheCurrentEvent (&osx->quit_event, &osx->quit_reply,
|
||||
NewAEEventHandlerUPP (quit_requested_resumed),
|
||||
(long)GPOINTER_TO_SIZE (client));
|
||||
AEDisposeDesc (&osx->quit_event);
|
||||
AEDisposeDesc (&osx->quit_reply);
|
||||
|
||||
if (osx->quitting)
|
||||
egg_sm_client_quit (client);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
sm_client_osx_will_quit (EggSMClient *client,
|
||||
gboolean will_quit)
|
||||
{
|
||||
EggSMClientOSX *osx = (EggSMClientOSX *)client;
|
||||
|
||||
g_return_if_fail (osx->quit_requested);
|
||||
|
||||
osx->quitting = will_quit;
|
||||
|
||||
/* Finish in an idle handler since the caller might have called
|
||||
* egg_sm_client_will_quit() from inside the "quit_requested" signal
|
||||
* handler, but may not expect the "quit" signal to arrive during
|
||||
* the _will_quit() call.
|
||||
*/
|
||||
g_idle_add (idle_will_quit, client);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sm_client_osx_end_session (EggSMClient *client,
|
||||
EggSMClientEndStyle style,
|
||||
gboolean request_confirmation)
|
||||
{
|
||||
static const ProcessSerialNumber loginwindow_psn = { 0, kSystemProcess };
|
||||
AppleEvent event = { typeNull, NULL }, reply = { typeNull, NULL };
|
||||
AEAddressDesc target;
|
||||
AEEventID id;
|
||||
OSErr err;
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case EGG_SM_CLIENT_END_SESSION_DEFAULT:
|
||||
case EGG_SM_CLIENT_LOGOUT:
|
||||
id = request_confirmation ? kAELogOut : kAEReallyLogOut;
|
||||
break;
|
||||
case EGG_SM_CLIENT_REBOOT:
|
||||
id = request_confirmation ? kAEShowRestartDialog : kAERestart;
|
||||
break;
|
||||
case EGG_SM_CLIENT_SHUTDOWN:
|
||||
id = request_confirmation ? kAEShowShutdownDialog : kAEShutDown;
|
||||
break;
|
||||
}
|
||||
|
||||
err = AECreateDesc (typeProcessSerialNumber, &loginwindow_psn,
|
||||
sizeof (loginwindow_psn), &target);
|
||||
if (err != noErr)
|
||||
{
|
||||
g_warning ("Could not create descriptor for loginwindow: %d", err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
err = AECreateAppleEvent (kCoreEventClass, id, &target,
|
||||
kAutoGenerateReturnID, kAnyTransactionID,
|
||||
&event);
|
||||
AEDisposeDesc (&target);
|
||||
if (err != noErr)
|
||||
{
|
||||
g_warning ("Could not create logout AppleEvent: %d", err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
err = AESend (&event, &reply, kAENoReply, kAENormalPriority,
|
||||
kAEDefaultTimeout, NULL, NULL);
|
||||
AEDisposeDesc (&event);
|
||||
if (err == noErr)
|
||||
AEDisposeDesc (&reply);
|
||||
|
||||
return err == noErr;
|
||||
}
|
@@ -33,22 +33,8 @@ void egg_sm_client_quit_requested (EggSMClient *client);
|
||||
void egg_sm_client_quit_cancelled (EggSMClient *client);
|
||||
void egg_sm_client_quit (EggSMClient *client);
|
||||
|
||||
#if defined (GDK_WINDOWING_X11)
|
||||
# ifdef EGG_SM_CLIENT_BACKEND_XSMP
|
||||
GType egg_sm_client_xsmp_get_type (void);
|
||||
EggSMClient *egg_sm_client_xsmp_new (void);
|
||||
# endif
|
||||
# ifdef EGG_SM_CLIENT_BACKEND_DBUS
|
||||
GType egg_sm_client_dbus_get_type (void);
|
||||
EggSMClient *egg_sm_client_dbus_new (void);
|
||||
# endif
|
||||
#elif defined (GDK_WINDOWING_WIN32)
|
||||
GType egg_sm_client_win32_get_type (void);
|
||||
EggSMClient *egg_sm_client_win32_new (void);
|
||||
#elif defined (GDK_WINDOWING_QUARTZ)
|
||||
GType egg_sm_client_osx_get_type (void);
|
||||
EggSMClient *egg_sm_client_osx_new (void);
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -1,353 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Novell, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* EggSMClientWin32
|
||||
*
|
||||
* For details on the Windows XP logout process, see:
|
||||
* http://msdn.microsoft.com/en-us/library/aa376876.aspx.
|
||||
*
|
||||
* Vista adds some new APIs which EggSMClient does not make use of; see
|
||||
* http://msdn.microsoft.com/en-us/library/ms700677(VS.85).aspx
|
||||
*
|
||||
* When shutting down, Windows sends every top-level window a
|
||||
* WM_QUERYENDSESSION event, which the application must respond to
|
||||
* synchronously, saying whether or not it will quit. To avoid main
|
||||
* loop re-entrancy problems (and to avoid having to muck about too
|
||||
* much with the guts of the gdk-win32 main loop), we watch for this
|
||||
* event in a separate thread, which then signals the main thread and
|
||||
* waits for the main thread to handle the event. Since we don't want
|
||||
* to require g_thread_init() to be called, we do this all using
|
||||
* Windows-specific thread methods.
|
||||
*
|
||||
* After the application handles the WM_QUERYENDSESSION event,
|
||||
* Windows then sends it a WM_ENDSESSION event with a TRUE or FALSE
|
||||
* parameter indicating whether the session is or is not actually
|
||||
* going to end now. We handle this from the other thread as well.
|
||||
*
|
||||
* As mentioned above, Vista introduces several additional new APIs
|
||||
* that don't fit into the (current) EggSMClient API. Windows also has
|
||||
* an entirely separate shutdown-notification scheme for non-GUI apps,
|
||||
* which we also don't handle here.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "eggsmclient-private.h"
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define UNICODE
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
#define EGG_TYPE_SM_CLIENT_WIN32 (egg_sm_client_win32_get_type ())
|
||||
#define EGG_SM_CLIENT_WIN32(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_WIN32, EggSMClientWin32))
|
||||
#define EGG_SM_CLIENT_WIN32_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_WIN32, EggSMClientWin32Class))
|
||||
#define EGG_IS_SM_CLIENT_WIN32(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_WIN32))
|
||||
#define EGG_IS_SM_CLIENT_WIN32_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_WIN32))
|
||||
#define EGG_SM_CLIENT_WIN32_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_WIN32, EggSMClientWin32Class))
|
||||
|
||||
typedef struct _EggSMClientWin32 EggSMClientWin32;
|
||||
typedef struct _EggSMClientWin32Class EggSMClientWin32Class;
|
||||
|
||||
struct _EggSMClientWin32 {
|
||||
EggSMClient parent;
|
||||
|
||||
HANDLE message_event, response_event;
|
||||
|
||||
volatile GSourceFunc event;
|
||||
volatile gboolean will_quit;
|
||||
};
|
||||
|
||||
struct _EggSMClientWin32Class
|
||||
{
|
||||
EggSMClientClass parent_class;
|
||||
|
||||
};
|
||||
|
||||
static void sm_client_win32_startup (EggSMClient *client,
|
||||
const char *client_id);
|
||||
static void sm_client_win32_will_quit (EggSMClient *client,
|
||||
gboolean will_quit);
|
||||
static gboolean sm_client_win32_end_session (EggSMClient *client,
|
||||
EggSMClientEndStyle style,
|
||||
gboolean request_confirmation);
|
||||
|
||||
static GSource *g_win32_handle_source_add (HANDLE handle, GSourceFunc callback,
|
||||
gpointer user_data);
|
||||
static gboolean got_message (gpointer user_data);
|
||||
static void sm_client_thread (gpointer data);
|
||||
|
||||
G_DEFINE_TYPE (EggSMClientWin32, egg_sm_client_win32, EGG_TYPE_SM_CLIENT)
|
||||
|
||||
static void
|
||||
egg_sm_client_win32_init (EggSMClientWin32 *win32)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_sm_client_win32_class_init (EggSMClientWin32Class *klass)
|
||||
{
|
||||
EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
|
||||
|
||||
sm_client_class->startup = sm_client_win32_startup;
|
||||
sm_client_class->will_quit = sm_client_win32_will_quit;
|
||||
sm_client_class->end_session = sm_client_win32_end_session;
|
||||
}
|
||||
|
||||
EggSMClient *
|
||||
egg_sm_client_win32_new (void)
|
||||
{
|
||||
return g_object_new (EGG_TYPE_SM_CLIENT_WIN32, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
sm_client_win32_startup (EggSMClient *client,
|
||||
const char *client_id)
|
||||
{
|
||||
EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
|
||||
|
||||
win32->message_event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
win32->response_event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
g_win32_handle_source_add (win32->message_event, got_message, win32);
|
||||
_beginthread (sm_client_thread, 0, client);
|
||||
}
|
||||
|
||||
static void
|
||||
sm_client_win32_will_quit (EggSMClient *client,
|
||||
gboolean will_quit)
|
||||
{
|
||||
EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
|
||||
|
||||
win32->will_quit = will_quit;
|
||||
SetEvent (win32->response_event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sm_client_win32_end_session (EggSMClient *client,
|
||||
EggSMClientEndStyle style,
|
||||
gboolean request_confirmation)
|
||||
{
|
||||
UINT uFlags = EWX_LOGOFF;
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case EGG_SM_CLIENT_END_SESSION_DEFAULT:
|
||||
case EGG_SM_CLIENT_LOGOUT:
|
||||
uFlags = EWX_LOGOFF;
|
||||
break;
|
||||
case EGG_SM_CLIENT_REBOOT:
|
||||
uFlags = EWX_REBOOT;
|
||||
break;
|
||||
case EGG_SM_CLIENT_SHUTDOWN:
|
||||
uFlags = EWX_POWEROFF;
|
||||
break;
|
||||
}
|
||||
|
||||
/* There's no way to make ExitWindowsEx() show a logout dialog, so
|
||||
* we ignore @request_confirmation.
|
||||
*/
|
||||
|
||||
#ifdef SHTDN_REASON_FLAG_PLANNED
|
||||
ExitWindowsEx (uFlags, SHTDN_REASON_FLAG_PLANNED);
|
||||
#else
|
||||
ExitWindowsEx (uFlags, 0);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* callbacks from logout-listener thread */
|
||||
|
||||
static gboolean
|
||||
emit_quit_requested (gpointer smclient)
|
||||
{
|
||||
gdk_threads_enter ();
|
||||
egg_sm_client_quit_requested (smclient);
|
||||
gdk_threads_leave ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
emit_quit (gpointer smclient)
|
||||
{
|
||||
EggSMClientWin32 *win32 = smclient;
|
||||
|
||||
gdk_threads_enter ();
|
||||
egg_sm_client_quit (smclient);
|
||||
gdk_threads_leave ();
|
||||
|
||||
SetEvent (win32->response_event);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
emit_quit_cancelled (gpointer smclient)
|
||||
{
|
||||
EggSMClientWin32 *win32 = smclient;
|
||||
|
||||
gdk_threads_enter ();
|
||||
egg_sm_client_quit_cancelled (smclient);
|
||||
gdk_threads_leave ();
|
||||
|
||||
SetEvent (win32->response_event);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
got_message (gpointer smclient)
|
||||
{
|
||||
EggSMClientWin32 *win32 = smclient;
|
||||
|
||||
win32->event (win32);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Windows HANDLE GSource */
|
||||
|
||||
typedef struct {
|
||||
GSource source;
|
||||
GPollFD pollfd;
|
||||
} GWin32HandleSource;
|
||||
|
||||
static gboolean
|
||||
g_win32_handle_source_prepare (GSource *source, gint *timeout)
|
||||
{
|
||||
*timeout = -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_win32_handle_source_check (GSource *source)
|
||||
{
|
||||
GWin32HandleSource *hsource = (GWin32HandleSource *)source;
|
||||
|
||||
return hsource->pollfd.revents;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_win32_handle_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
|
||||
{
|
||||
return (*callback) (user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
g_win32_handle_source_finalize (GSource *source)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
GSourceFuncs g_win32_handle_source_funcs = {
|
||||
g_win32_handle_source_prepare,
|
||||
g_win32_handle_source_check,
|
||||
g_win32_handle_source_dispatch,
|
||||
g_win32_handle_source_finalize
|
||||
};
|
||||
|
||||
static GSource *
|
||||
g_win32_handle_source_add (HANDLE handle, GSourceFunc callback, gpointer user_data)
|
||||
{
|
||||
GWin32HandleSource *hsource;
|
||||
GSource *source;
|
||||
|
||||
source = g_source_new (&g_win32_handle_source_funcs, sizeof (GWin32HandleSource));
|
||||
hsource = (GWin32HandleSource *)source;
|
||||
hsource->pollfd.fd = (int)handle;
|
||||
hsource->pollfd.events = G_IO_IN;
|
||||
hsource->pollfd.revents = 0;
|
||||
g_source_add_poll (source, &hsource->pollfd);
|
||||
|
||||
g_source_set_callback (source, callback, user_data, NULL);
|
||||
g_source_attach (source, NULL);
|
||||
return source;
|
||||
}
|
||||
|
||||
/* logout-listener thread */
|
||||
|
||||
LRESULT CALLBACK
|
||||
sm_client_win32_window_procedure (HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
EggSMClientWin32 *win32 =
|
||||
(EggSMClientWin32 *)GetWindowLongPtr (hwnd, GWLP_USERDATA);
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_QUERYENDSESSION:
|
||||
win32->event = emit_quit_requested;
|
||||
SetEvent (win32->message_event);
|
||||
|
||||
WaitForSingleObject (win32->response_event, INFINITE);
|
||||
return win32->will_quit;
|
||||
|
||||
case WM_ENDSESSION:
|
||||
if (wParam)
|
||||
{
|
||||
/* The session is ending */
|
||||
win32->event = emit_quit;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nope, the session *isn't* ending */
|
||||
win32->event = emit_quit_cancelled;
|
||||
}
|
||||
|
||||
SetEvent (win32->message_event);
|
||||
WaitForSingleObject (win32->response_event, INFINITE);
|
||||
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return DefWindowProc (hwnd, message, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sm_client_thread (gpointer smclient)
|
||||
{
|
||||
HINSTANCE instance;
|
||||
WNDCLASSEXW wcl;
|
||||
ATOM klass;
|
||||
HWND window;
|
||||
MSG msg;
|
||||
|
||||
instance = GetModuleHandle (NULL);
|
||||
|
||||
memset (&wcl, 0, sizeof (WNDCLASSEX));
|
||||
wcl.cbSize = sizeof (WNDCLASSEX);
|
||||
wcl.lpfnWndProc = sm_client_win32_window_procedure;
|
||||
wcl.hInstance = instance;
|
||||
wcl.lpszClassName = L"EggSmClientWindow";
|
||||
klass = RegisterClassEx (&wcl);
|
||||
|
||||
window = CreateWindowEx (0, MAKEINTRESOURCE (klass),
|
||||
L"EggSmClientWindow", 0,
|
||||
10, 10, 50, 50, GetDesktopWindow (),
|
||||
NULL, instance, NULL);
|
||||
SetWindowLongPtr (window, GWLP_USERDATA, (LONG_PTR)smclient);
|
||||
|
||||
/* main loop */
|
||||
while (GetMessage (&msg, NULL, 0, 0))
|
||||
DispatchMessage (&msg);
|
||||
}
|
@@ -320,23 +320,7 @@ egg_sm_client_get (void)
|
||||
if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
|
||||
!sm_client_disable)
|
||||
{
|
||||
#if defined (GDK_WINDOWING_WIN32)
|
||||
global_client = egg_sm_client_win32_new ();
|
||||
#elif defined (GDK_WINDOWING_QUARTZ)
|
||||
global_client = egg_sm_client_osx_new ();
|
||||
#else
|
||||
/* If both D-Bus and XSMP are compiled in, try XSMP first
|
||||
* (since it supports state saving) and fall back to D-Bus
|
||||
* if XSMP isn't available.
|
||||
*/
|
||||
# ifdef EGG_SM_CLIENT_BACKEND_XSMP
|
||||
global_client = egg_sm_client_xsmp_new ();
|
||||
# endif
|
||||
# ifdef EGG_SM_CLIENT_BACKEND_DBUS
|
||||
if (!global_client)
|
||||
global_client = egg_sm_client_dbus_new ();
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Fallback: create a dummy client, so that callers don't have
|
||||
|
Reference in New Issue
Block a user