aplicando formato allman

master-1.22
Perberos 2011-11-06 19:14:03 -03:00
parent def492f92d
commit f2a13175e5
48 changed files with 14188 additions and 13836 deletions

File diff suppressed because it is too large Load Diff

View File

@ -26,25 +26,26 @@ G_BEGIN_DECLS
typedef struct EggDesktopFile EggDesktopFile; typedef struct EggDesktopFile EggDesktopFile;
typedef enum { typedef enum
EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED, {
EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED,
EGG_DESKTOP_FILE_TYPE_APPLICATION, EGG_DESKTOP_FILE_TYPE_APPLICATION,
EGG_DESKTOP_FILE_TYPE_LINK, EGG_DESKTOP_FILE_TYPE_LINK,
EGG_DESKTOP_FILE_TYPE_DIRECTORY EGG_DESKTOP_FILE_TYPE_DIRECTORY
} EggDesktopFileType; } EggDesktopFileType;
EggDesktopFile *egg_desktop_file_new (const char *desktop_file_path, EggDesktopFile *egg_desktop_file_new (const char *desktop_file_path,
GError **error); GError **error);
EggDesktopFile *egg_desktop_file_new_from_data_dirs (const char *desktop_file_path, EggDesktopFile *egg_desktop_file_new_from_data_dirs (const char *desktop_file_path,
GError **error); GError **error);
EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path, EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path,
const char **search_dirs, const char **search_dirs,
GError **error); GError **error);
EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file, EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file,
const char *source, const char *source,
GError **error); GError **error);
void egg_desktop_file_free (EggDesktopFile *desktop_file); void egg_desktop_file_free (EggDesktopFile *desktop_file);
@ -56,35 +57,36 @@ const char *egg_desktop_file_get_name (EggDesktopFile *deskto
const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file); const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file);
gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file, gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file,
const char *desktop_environment); const char *desktop_environment);
gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file); gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file);
gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file); gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file);
gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file); gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file);
char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file, char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file,
GSList *documents, GSList *documents,
GError **error); GError **error);
gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file, gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file,
GSList *documents, GSList *documents,
GError **error, GError **error,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
typedef enum { typedef enum
EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1, {
EGG_DESKTOP_FILE_LAUNCH_PUTENV, EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1,
EGG_DESKTOP_FILE_LAUNCH_SCREEN, EGG_DESKTOP_FILE_LAUNCH_PUTENV,
EGG_DESKTOP_FILE_LAUNCH_WORKSPACE, EGG_DESKTOP_FILE_LAUNCH_SCREEN,
EGG_DESKTOP_FILE_LAUNCH_DIRECTORY, EGG_DESKTOP_FILE_LAUNCH_WORKSPACE,
EGG_DESKTOP_FILE_LAUNCH_TIME, EGG_DESKTOP_FILE_LAUNCH_DIRECTORY,
EGG_DESKTOP_FILE_LAUNCH_FLAGS, EGG_DESKTOP_FILE_LAUNCH_TIME,
EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC, EGG_DESKTOP_FILE_LAUNCH_FLAGS,
EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE, EGG_DESKTOP_FILE_LAUNCH_RETURN_PID,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE, EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE, EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID
} EggDesktopFileLaunchOption; } EggDesktopFileLaunchOption;
/* Standard Keys */ /* Standard Keys */
@ -112,30 +114,30 @@ typedef enum {
/* Accessors */ /* Accessors */
gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file, gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file,
const char *key, const char *key,
GError **error); GError **error);
char *egg_desktop_file_get_string (EggDesktopFile *desktop_file, char *egg_desktop_file_get_string (EggDesktopFile *desktop_file,
const char *key, const char *key,
GError **error) G_GNUC_MALLOC; GError **error) G_GNUC_MALLOC;
char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file, char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file,
const char *key, const char *key,
const char *locale, const char *locale,
GError **error) G_GNUC_MALLOC; GError **error) G_GNUC_MALLOC;
gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file, gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file,
const char *key, const char *key,
GError **error); GError **error);
double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file, double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file,
const char *key, const char *key,
GError **error); GError **error);
char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file, char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file,
const char *key, const char *key,
gsize *length, gsize *length,
GError **error) G_GNUC_MALLOC; GError **error) G_GNUC_MALLOC;
char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file, char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file,
const char *key, const char *key,
const char *locale, const char *locale,
gsize *length, gsize *length,
GError **error) G_GNUC_MALLOC; GError **error) G_GNUC_MALLOC;
/* Errors */ /* Errors */
@ -143,10 +145,11 @@ char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file
GQuark egg_desktop_file_error_quark (void); GQuark egg_desktop_file_error_quark (void);
typedef enum { typedef enum
EGG_DESKTOP_FILE_ERROR_INVALID, {
EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, EGG_DESKTOP_FILE_ERROR_INVALID,
EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
} EggDesktopFileError; } EggDesktopFileError;
/* Global application desktop file */ /* Global application desktop file */

View File

@ -60,7 +60,8 @@ egg_shell (const char *shell)
#ifndef G_OS_WIN32 #ifndef G_OS_WIN32
struct passwd *pw; struct passwd *pw;
int i; int i;
static const char shells [][14] = { static const char shells [][14] =
{
/* Note that on some systems shells can also /* Note that on some systems shells can also
* be installed in /usr/bin */ * be installed in /usr/bin */
"/bin/bash", "/usr/bin/bash", "/bin/bash", "/usr/bin/bash",
@ -71,23 +72,30 @@ egg_shell (const char *shell)
}; };
if (geteuid () == getuid () && if (geteuid () == getuid () &&
getegid () == getgid ()) { getegid () == getgid ())
{
/* only in non-setuid */ /* only in non-setuid */
if (shell != NULL) { if (shell != NULL)
if (access (shell, X_OK) == 0) { {
if (access (shell, X_OK) == 0)
{
return g_strdup (shell); return g_strdup (shell);
} }
} }
} }
pw = getpwuid(getuid()); pw = getpwuid(getuid());
if (pw && pw->pw_shell) { if (pw && pw->pw_shell)
if (access (pw->pw_shell, X_OK) == 0) { {
if (access (pw->pw_shell, X_OK) == 0)
{
return g_strdup (pw->pw_shell); return g_strdup (pw->pw_shell);
} }
} }
for (i = 0; i != G_N_ELEMENTS (shells); i++) { for (i = 0; i != G_N_ELEMENTS (shells); i++)
if (access (shells [i], X_OK) == 0) { {
if (access (shells [i], X_OK) == 0)
{
return g_strdup (shells[i]); return g_strdup (shells[i]);
} }
} }

View File

@ -51,26 +51,27 @@
typedef struct _EggSMClientOSX EggSMClientOSX; typedef struct _EggSMClientOSX EggSMClientOSX;
typedef struct _EggSMClientOSXClass EggSMClientOSXClass; typedef struct _EggSMClientOSXClass EggSMClientOSXClass;
struct _EggSMClientOSX { struct _EggSMClientOSX
EggSMClient parent; {
EggSMClient parent;
AppleEvent quit_event, quit_reply; AppleEvent quit_event, quit_reply;
gboolean quit_requested, quitting; gboolean quit_requested, quitting;
}; };
struct _EggSMClientOSXClass struct _EggSMClientOSXClass
{ {
EggSMClientClass parent_class; EggSMClientClass parent_class;
}; };
static void sm_client_osx_startup (EggSMClient *client, static void sm_client_osx_startup (EggSMClient *client,
const char *client_id); const char *client_id);
static void sm_client_osx_will_quit (EggSMClient *client, static void sm_client_osx_will_quit (EggSMClient *client,
gboolean will_quit); gboolean will_quit);
static gboolean sm_client_osx_end_session (EggSMClient *client, static gboolean sm_client_osx_end_session (EggSMClient *client,
EggSMClientEndStyle style, EggSMClientEndStyle style,
gboolean request_confirmation); gboolean request_confirmation);
static pascal OSErr quit_requested (const AppleEvent *, AppleEvent *, long); static pascal OSErr quit_requested (const AppleEvent *, AppleEvent *, long);
@ -79,157 +80,157 @@ G_DEFINE_TYPE (EggSMClientOSX, egg_sm_client_osx, EGG_TYPE_SM_CLIENT)
static void static void
egg_sm_client_osx_init (EggSMClientOSX *osx) egg_sm_client_osx_init (EggSMClientOSX *osx)
{ {
; ;
} }
static void static void
egg_sm_client_osx_class_init (EggSMClientOSXClass *klass) egg_sm_client_osx_class_init (EggSMClientOSXClass *klass)
{ {
EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass); EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
sm_client_class->startup = sm_client_osx_startup; sm_client_class->startup = sm_client_osx_startup;
sm_client_class->will_quit = sm_client_osx_will_quit; sm_client_class->will_quit = sm_client_osx_will_quit;
sm_client_class->end_session = sm_client_osx_end_session; sm_client_class->end_session = sm_client_osx_end_session;
} }
EggSMClient * EggSMClient *
egg_sm_client_osx_new (void) egg_sm_client_osx_new (void)
{ {
return g_object_new (EGG_TYPE_SM_CLIENT_OSX, NULL); return g_object_new (EGG_TYPE_SM_CLIENT_OSX, NULL);
} }
static void static void
sm_client_osx_startup (EggSMClient *client, sm_client_osx_startup (EggSMClient *client,
const char *client_id) const char *client_id)
{ {
AEInstallEventHandler (kCoreEventClass, kAEQuitApplication, AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
NewAEEventHandlerUPP (quit_requested), NewAEEventHandlerUPP (quit_requested),
(long)GPOINTER_TO_SIZE (client), false); (long)GPOINTER_TO_SIZE (client), false);
} }
static gboolean static gboolean
idle_quit_requested (gpointer client) idle_quit_requested (gpointer client)
{ {
egg_sm_client_quit_requested (client); egg_sm_client_quit_requested (client);
return FALSE; return FALSE;
} }
static pascal OSErr static pascal OSErr
quit_requested (const AppleEvent *aevt, AppleEvent *reply, long refcon) quit_requested (const AppleEvent *aevt, AppleEvent *reply, long refcon)
{ {
EggSMClient *client = GSIZE_TO_POINTER ((gsize)refcon); EggSMClient *client = GSIZE_TO_POINTER ((gsize)refcon);
EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon); EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon);
g_return_val_if_fail (!osx->quit_requested, userCanceledErr); g_return_val_if_fail (!osx->quit_requested, userCanceledErr);
/* FIXME AEInteractWithUser? */
osx->quit_requested = TRUE; /* FIXME AEInteractWithUser? */
AEDuplicateDesc (aevt, &osx->quit_event);
AEDuplicateDesc (reply, &osx->quit_reply);
AESuspendTheCurrentEvent (aevt);
/* Don't emit the "quit_requested" signal immediately, since we're osx->quit_requested = TRUE;
* called from a weird point in the guts of gdkeventloop-quartz.c AEDuplicateDesc (aevt, &osx->quit_event);
*/ AEDuplicateDesc (reply, &osx->quit_reply);
g_idle_add (idle_quit_requested, client); AESuspendTheCurrentEvent (aevt);
return noErr;
/* 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 static pascal OSErr
quit_requested_resumed (const AppleEvent *aevt, AppleEvent *reply, long refcon) quit_requested_resumed (const AppleEvent *aevt, AppleEvent *reply, long refcon)
{ {
EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon); EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon);
osx->quit_requested = FALSE; osx->quit_requested = FALSE;
return osx->quitting ? noErr : userCanceledErr; return osx->quitting ? noErr : userCanceledErr;
} }
static gboolean static gboolean
idle_will_quit (gpointer client) idle_will_quit (gpointer client)
{ {
EggSMClientOSX *osx = (EggSMClientOSX *)client; EggSMClientOSX *osx = (EggSMClientOSX *)client;
/* Resume the event with a new handler that will return a value to /* Resume the event with a new handler that will return a value to
* the system. * the system.
*/ */
AEResumeTheCurrentEvent (&osx->quit_event, &osx->quit_reply, AEResumeTheCurrentEvent (&osx->quit_event, &osx->quit_reply,
NewAEEventHandlerUPP (quit_requested_resumed), NewAEEventHandlerUPP (quit_requested_resumed),
(long)GPOINTER_TO_SIZE (client)); (long)GPOINTER_TO_SIZE (client));
AEDisposeDesc (&osx->quit_event); AEDisposeDesc (&osx->quit_event);
AEDisposeDesc (&osx->quit_reply); AEDisposeDesc (&osx->quit_reply);
if (osx->quitting) if (osx->quitting)
egg_sm_client_quit (client); egg_sm_client_quit (client);
return FALSE; return FALSE;
} }
static void static void
sm_client_osx_will_quit (EggSMClient *client, sm_client_osx_will_quit (EggSMClient *client,
gboolean will_quit) gboolean will_quit)
{ {
EggSMClientOSX *osx = (EggSMClientOSX *)client; EggSMClientOSX *osx = (EggSMClientOSX *)client;
g_return_if_fail (osx->quit_requested); g_return_if_fail (osx->quit_requested);
osx->quitting = will_quit; osx->quitting = will_quit;
/* Finish in an idle handler since the caller might have called /* Finish in an idle handler since the caller might have called
* egg_sm_client_will_quit() from inside the "quit_requested" signal * egg_sm_client_will_quit() from inside the "quit_requested" signal
* handler, but may not expect the "quit" signal to arrive during * handler, but may not expect the "quit" signal to arrive during
* the _will_quit() call. * the _will_quit() call.
*/ */
g_idle_add (idle_will_quit, client); g_idle_add (idle_will_quit, client);
} }
static gboolean static gboolean
sm_client_osx_end_session (EggSMClient *client, sm_client_osx_end_session (EggSMClient *client,
EggSMClientEndStyle style, EggSMClientEndStyle style,
gboolean request_confirmation) gboolean request_confirmation)
{ {
static const ProcessSerialNumber loginwindow_psn = { 0, kSystemProcess }; static const ProcessSerialNumber loginwindow_psn = { 0, kSystemProcess };
AppleEvent event = { typeNull, NULL }, reply = { typeNull, NULL }; AppleEvent event = { typeNull, NULL }, reply = { typeNull, NULL };
AEAddressDesc target; AEAddressDesc target;
AEEventID id; AEEventID id;
OSErr err; OSErr err;
switch (style) switch (style)
{ {
case EGG_SM_CLIENT_END_SESSION_DEFAULT: case EGG_SM_CLIENT_END_SESSION_DEFAULT:
case EGG_SM_CLIENT_LOGOUT: case EGG_SM_CLIENT_LOGOUT:
id = request_confirmation ? kAELogOut : kAEReallyLogOut; id = request_confirmation ? kAELogOut : kAEReallyLogOut;
break; break;
case EGG_SM_CLIENT_REBOOT: case EGG_SM_CLIENT_REBOOT:
id = request_confirmation ? kAEShowRestartDialog : kAERestart; id = request_confirmation ? kAEShowRestartDialog : kAERestart;
break; break;
case EGG_SM_CLIENT_SHUTDOWN: case EGG_SM_CLIENT_SHUTDOWN:
id = request_confirmation ? kAEShowShutdownDialog : kAEShutDown; id = request_confirmation ? kAEShowShutdownDialog : kAEShutDown;
break; break;
} }
err = AECreateDesc (typeProcessSerialNumber, &loginwindow_psn, err = AECreateDesc (typeProcessSerialNumber, &loginwindow_psn,
sizeof (loginwindow_psn), &target); sizeof (loginwindow_psn), &target);
if (err != noErr) if (err != noErr)
{ {
g_warning ("Could not create descriptor for loginwindow: %d", err); g_warning ("Could not create descriptor for loginwindow: %d", err);
return FALSE; return FALSE;
} }
err = AECreateAppleEvent (kCoreEventClass, id, &target, err = AECreateAppleEvent (kCoreEventClass, id, &target,
kAutoGenerateReturnID, kAnyTransactionID, kAutoGenerateReturnID, kAnyTransactionID,
&event); &event);
AEDisposeDesc (&target); AEDisposeDesc (&target);
if (err != noErr) if (err != noErr)
{ {
g_warning ("Could not create logout AppleEvent: %d", err); g_warning ("Could not create logout AppleEvent: %d", err);
return FALSE; return FALSE;
} }
err = AESend (&event, &reply, kAENoReply, kAENormalPriority, err = AESend (&event, &reply, kAENoReply, kAENormalPriority,
kAEDefaultTimeout, NULL, NULL); kAEDefaultTimeout, NULL, NULL);
AEDisposeDesc (&event); AEDisposeDesc (&event);
if (err == noErr) if (err == noErr)
AEDisposeDesc (&reply); AEDisposeDesc (&reply);
return err == noErr; return err == noErr;
} }

View File

@ -66,31 +66,32 @@
typedef struct _EggSMClientWin32 EggSMClientWin32; typedef struct _EggSMClientWin32 EggSMClientWin32;
typedef struct _EggSMClientWin32Class EggSMClientWin32Class; typedef struct _EggSMClientWin32Class EggSMClientWin32Class;
struct _EggSMClientWin32 { struct _EggSMClientWin32
EggSMClient parent; {
EggSMClient parent;
HANDLE message_event, response_event; HANDLE message_event, response_event;
volatile GSourceFunc event; volatile GSourceFunc event;
volatile gboolean will_quit; volatile gboolean will_quit;
}; };
struct _EggSMClientWin32Class struct _EggSMClientWin32Class
{ {
EggSMClientClass parent_class; EggSMClientClass parent_class;
}; };
static void sm_client_win32_startup (EggSMClient *client, static void sm_client_win32_startup (EggSMClient *client,
const char *client_id); const char *client_id);
static void sm_client_win32_will_quit (EggSMClient *client, static void sm_client_win32_will_quit (EggSMClient *client,
gboolean will_quit); gboolean will_quit);
static gboolean sm_client_win32_end_session (EggSMClient *client, static gboolean sm_client_win32_end_session (EggSMClient *client,
EggSMClientEndStyle style, EggSMClientEndStyle style,
gboolean request_confirmation); gboolean request_confirmation);
static GSource *g_win32_handle_source_add (HANDLE handle, GSourceFunc callback, static GSource *g_win32_handle_source_add (HANDLE handle, GSourceFunc callback,
gpointer user_data); gpointer user_data);
static gboolean got_message (gpointer user_data); static gboolean got_message (gpointer user_data);
static void sm_client_thread (gpointer data); static void sm_client_thread (gpointer data);
@ -99,79 +100,79 @@ G_DEFINE_TYPE (EggSMClientWin32, egg_sm_client_win32, EGG_TYPE_SM_CLIENT)
static void static void
egg_sm_client_win32_init (EggSMClientWin32 *win32) egg_sm_client_win32_init (EggSMClientWin32 *win32)
{ {
; ;
} }
static void static void
egg_sm_client_win32_class_init (EggSMClientWin32Class *klass) egg_sm_client_win32_class_init (EggSMClientWin32Class *klass)
{ {
EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass); EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
sm_client_class->startup = sm_client_win32_startup; sm_client_class->startup = sm_client_win32_startup;
sm_client_class->will_quit = sm_client_win32_will_quit; sm_client_class->will_quit = sm_client_win32_will_quit;
sm_client_class->end_session = sm_client_win32_end_session; sm_client_class->end_session = sm_client_win32_end_session;
} }
EggSMClient * EggSMClient *
egg_sm_client_win32_new (void) egg_sm_client_win32_new (void)
{ {
return g_object_new (EGG_TYPE_SM_CLIENT_WIN32, NULL); return g_object_new (EGG_TYPE_SM_CLIENT_WIN32, NULL);
} }
static void static void
sm_client_win32_startup (EggSMClient *client, sm_client_win32_startup (EggSMClient *client,
const char *client_id) const char *client_id)
{ {
EggSMClientWin32 *win32 = (EggSMClientWin32 *)client; EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
win32->message_event = CreateEvent (NULL, FALSE, FALSE, NULL); win32->message_event = CreateEvent (NULL, FALSE, FALSE, NULL);
win32->response_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); g_win32_handle_source_add (win32->message_event, got_message, win32);
_beginthread (sm_client_thread, 0, client); _beginthread (sm_client_thread, 0, client);
} }
static void static void
sm_client_win32_will_quit (EggSMClient *client, sm_client_win32_will_quit (EggSMClient *client,
gboolean will_quit) gboolean will_quit)
{ {
EggSMClientWin32 *win32 = (EggSMClientWin32 *)client; EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
win32->will_quit = will_quit; win32->will_quit = will_quit;
SetEvent (win32->response_event); SetEvent (win32->response_event);
} }
static gboolean static gboolean
sm_client_win32_end_session (EggSMClient *client, sm_client_win32_end_session (EggSMClient *client,
EggSMClientEndStyle style, EggSMClientEndStyle style,
gboolean request_confirmation) gboolean request_confirmation)
{ {
UINT uFlags = EWX_LOGOFF; UINT uFlags = EWX_LOGOFF;
switch (style) switch (style)
{ {
case EGG_SM_CLIENT_END_SESSION_DEFAULT: case EGG_SM_CLIENT_END_SESSION_DEFAULT:
case EGG_SM_CLIENT_LOGOUT: case EGG_SM_CLIENT_LOGOUT:
uFlags = EWX_LOGOFF; uFlags = EWX_LOGOFF;
break; break;
case EGG_SM_CLIENT_REBOOT: case EGG_SM_CLIENT_REBOOT:
uFlags = EWX_REBOOT; uFlags = EWX_REBOOT;
break; break;
case EGG_SM_CLIENT_SHUTDOWN: case EGG_SM_CLIENT_SHUTDOWN:
uFlags = EWX_POWEROFF; uFlags = EWX_POWEROFF;
break; break;
} }
/* There's no way to make ExitWindowsEx() show a logout dialog, so /* There's no way to make ExitWindowsEx() show a logout dialog, so
* we ignore @request_confirmation. * we ignore @request_confirmation.
*/ */
#ifdef SHTDN_REASON_FLAG_PLANNED #ifdef SHTDN_REASON_FLAG_PLANNED
ExitWindowsEx (uFlags, SHTDN_REASON_FLAG_PLANNED); ExitWindowsEx (uFlags, SHTDN_REASON_FLAG_PLANNED);
#else #else
ExitWindowsEx (uFlags, 0); ExitWindowsEx (uFlags, 0);
#endif #endif
return TRUE; return TRUE;
} }
@ -180,174 +181,176 @@ sm_client_win32_end_session (EggSMClient *client,
static gboolean static gboolean
emit_quit_requested (gpointer smclient) emit_quit_requested (gpointer smclient)
{ {
gdk_threads_enter (); gdk_threads_enter ();
egg_sm_client_quit_requested (smclient); egg_sm_client_quit_requested (smclient);
gdk_threads_leave (); gdk_threads_leave ();
return FALSE; return FALSE;
} }
static gboolean static gboolean
emit_quit (gpointer smclient) emit_quit (gpointer smclient)
{ {
EggSMClientWin32 *win32 = smclient; EggSMClientWin32 *win32 = smclient;
gdk_threads_enter (); gdk_threads_enter ();
egg_sm_client_quit (smclient); egg_sm_client_quit (smclient);
gdk_threads_leave (); gdk_threads_leave ();
SetEvent (win32->response_event); SetEvent (win32->response_event);
return FALSE; return FALSE;
} }
static gboolean static gboolean
emit_quit_cancelled (gpointer smclient) emit_quit_cancelled (gpointer smclient)
{ {
EggSMClientWin32 *win32 = smclient; EggSMClientWin32 *win32 = smclient;
gdk_threads_enter (); gdk_threads_enter ();
egg_sm_client_quit_cancelled (smclient); egg_sm_client_quit_cancelled (smclient);
gdk_threads_leave (); gdk_threads_leave ();
SetEvent (win32->response_event); SetEvent (win32->response_event);
return FALSE; return FALSE;
} }
static gboolean static gboolean
got_message (gpointer smclient) got_message (gpointer smclient)
{ {
EggSMClientWin32 *win32 = smclient; EggSMClientWin32 *win32 = smclient;
win32->event (win32); win32->event (win32);
return TRUE; return TRUE;
} }
/* Windows HANDLE GSource */ /* Windows HANDLE GSource */
typedef struct { typedef struct
GSource source; {
GPollFD pollfd; GSource source;
GPollFD pollfd;
} GWin32HandleSource; } GWin32HandleSource;
static gboolean static gboolean
g_win32_handle_source_prepare (GSource *source, gint *timeout) g_win32_handle_source_prepare (GSource *source, gint *timeout)
{ {
*timeout = -1; *timeout = -1;
return FALSE; return FALSE;
} }
static gboolean static gboolean
g_win32_handle_source_check (GSource *source) g_win32_handle_source_check (GSource *source)
{ {
GWin32HandleSource *hsource = (GWin32HandleSource *)source; GWin32HandleSource *hsource = (GWin32HandleSource *)source;
return hsource->pollfd.revents; return hsource->pollfd.revents;
} }
static gboolean static gboolean
g_win32_handle_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) g_win32_handle_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
{ {
return (*callback) (user_data); return (*callback) (user_data);
} }
static void static void
g_win32_handle_source_finalize (GSource *source) g_win32_handle_source_finalize (GSource *source)
{ {
; ;
} }
GSourceFuncs g_win32_handle_source_funcs = { GSourceFuncs g_win32_handle_source_funcs =
g_win32_handle_source_prepare, {
g_win32_handle_source_check, g_win32_handle_source_prepare,
g_win32_handle_source_dispatch, g_win32_handle_source_check,
g_win32_handle_source_finalize g_win32_handle_source_dispatch,
g_win32_handle_source_finalize
}; };
static GSource * static GSource *
g_win32_handle_source_add (HANDLE handle, GSourceFunc callback, gpointer user_data) g_win32_handle_source_add (HANDLE handle, GSourceFunc callback, gpointer user_data)
{ {
GWin32HandleSource *hsource; GWin32HandleSource *hsource;
GSource *source; GSource *source;
source = g_source_new (&g_win32_handle_source_funcs, sizeof (GWin32HandleSource)); source = g_source_new (&g_win32_handle_source_funcs, sizeof (GWin32HandleSource));
hsource = (GWin32HandleSource *)source; hsource = (GWin32HandleSource *)source;
hsource->pollfd.fd = (int)handle; hsource->pollfd.fd = (int)handle;
hsource->pollfd.events = G_IO_IN; hsource->pollfd.events = G_IO_IN;
hsource->pollfd.revents = 0; hsource->pollfd.revents = 0;
g_source_add_poll (source, &hsource->pollfd); g_source_add_poll (source, &hsource->pollfd);
g_source_set_callback (source, callback, user_data, NULL); g_source_set_callback (source, callback, user_data, NULL);
g_source_attach (source, NULL); g_source_attach (source, NULL);
return source; return source;
} }
/* logout-listener thread */ /* logout-listener thread */
LRESULT CALLBACK LRESULT CALLBACK
sm_client_win32_window_procedure (HWND hwnd, sm_client_win32_window_procedure (HWND hwnd,
UINT message, UINT message,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
EggSMClientWin32 *win32 = EggSMClientWin32 *win32 =
(EggSMClientWin32 *)GetWindowLongPtr (hwnd, GWLP_USERDATA); (EggSMClientWin32 *)GetWindowLongPtr (hwnd, GWLP_USERDATA);
switch (message) 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 */ case WM_QUERYENDSESSION:
win32->event = emit_quit; 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);
} }
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 static void
sm_client_thread (gpointer smclient) sm_client_thread (gpointer smclient)
{ {
HINSTANCE instance; HINSTANCE instance;
WNDCLASSEXW wcl; WNDCLASSEXW wcl;
ATOM klass; ATOM klass;
HWND window; HWND window;
MSG msg; MSG msg;
instance = GetModuleHandle (NULL); instance = GetModuleHandle (NULL);
memset (&wcl, 0, sizeof (WNDCLASSEX)); memset (&wcl, 0, sizeof (WNDCLASSEX));
wcl.cbSize = sizeof (WNDCLASSEX); wcl.cbSize = sizeof (WNDCLASSEX);
wcl.lpfnWndProc = sm_client_win32_window_procedure; wcl.lpfnWndProc = sm_client_win32_window_procedure;
wcl.hInstance = instance; wcl.hInstance = instance;
wcl.lpszClassName = L"EggSmClientWindow"; wcl.lpszClassName = L"EggSmClientWindow";
klass = RegisterClassEx (&wcl); klass = RegisterClassEx (&wcl);
window = CreateWindowEx (0, MAKEINTRESOURCE (klass), window = CreateWindowEx (0, MAKEINTRESOURCE (klass),
L"EggSmClientWindow", 0, L"EggSmClientWindow", 0,
10, 10, 50, 50, GetDesktopWindow (), 10, 10, 50, 50, GetDesktopWindow (),
NULL, instance, NULL); NULL, instance, NULL);
SetWindowLongPtr (window, GWLP_USERDATA, (LONG_PTR)smclient); SetWindowLongPtr (window, GWLP_USERDATA, (LONG_PTR)smclient);
/* main loop */ /* main loop */
while (GetMessage (&msg, NULL, 0, 0)) while (GetMessage (&msg, NULL, 0, 0))
DispatchMessage (&msg); DispatchMessage (&msg);
} }

File diff suppressed because it is too large Load Diff

View File

@ -26,22 +26,24 @@
#include "eggsmclient-private.h" #include "eggsmclient-private.h"
static void egg_sm_client_debug_handler (const char *log_domain, static void egg_sm_client_debug_handler (const char *log_domain,
GLogLevelFlags log_level, GLogLevelFlags log_level,
const char *message, const char *message,
gpointer user_data); gpointer user_data);
enum { enum
SAVE_STATE, {
QUIT_REQUESTED, SAVE_STATE,
QUIT_CANCELLED, QUIT_REQUESTED,
QUIT, QUIT_CANCELLED,
LAST_SIGNAL QUIT,
LAST_SIGNAL
}; };
static guint signals[LAST_SIGNAL]; static guint signals[LAST_SIGNAL];
struct _EggSMClientPrivate { struct _EggSMClientPrivate
GKeyFile *state_file; {
GKeyFile *state_file;
}; };
#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate)) #define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate))
@ -54,125 +56,125 @@ static EggSMClientMode global_client_mode = EGG_SM_CLIENT_MODE_NORMAL;
static void static void
egg_sm_client_init (EggSMClient *client) egg_sm_client_init (EggSMClient *client)
{ {
; ;
} }
static void static void
egg_sm_client_class_init (EggSMClientClass *klass) egg_sm_client_class_init (EggSMClientClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (EggSMClientPrivate)); g_type_class_add_private (klass, sizeof (EggSMClientPrivate));
/** /**
* EggSMClient::save_state: * EggSMClient::save_state:
* @client: the client * @client: the client
* @state_file: a #GKeyFile to save state information into * @state_file: a #GKeyFile to save state information into
* *
* Emitted when the session manager has requested that the * Emitted when the session manager has requested that the
* application save information about its current state. The * application save information about its current state. The
* application should save its state into @state_file, and then the * application should save its state into @state_file, and then the
* session manager may then restart the application in a future * session manager may then restart the application in a future
* session and tell it to initialize itself from that state. * session and tell it to initialize itself from that state.
* *
* You should not save any data into @state_file's "start group" * You should not save any data into @state_file's "start group"
* (ie, the %NULL group). Instead, applications should save their * (ie, the %NULL group). Instead, applications should save their
* data into groups with names that start with the application name, * data into groups with names that start with the application name,
* and libraries that connect to this signal should save their data * and libraries that connect to this signal should save their data
* into groups with names that start with the library name. * into groups with names that start with the library name.
* *
* Alternatively, rather than (or in addition to) using @state_file, * Alternatively, rather than (or in addition to) using @state_file,
* the application can save its state by calling * the application can save its state by calling
* egg_sm_client_set_restart_command() during the processing of this * egg_sm_client_set_restart_command() during the processing of this
* signal (eg, to include a list of files to open). * signal (eg, to include a list of files to open).
**/ **/
signals[SAVE_STATE] = signals[SAVE_STATE] =
g_signal_new ("save_state", g_signal_new ("save_state",
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, save_state), G_STRUCT_OFFSET (EggSMClientClass, save_state),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__POINTER, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, G_TYPE_NONE,
1, G_TYPE_POINTER); 1, G_TYPE_POINTER);
/** /**
* EggSMClient::quit_requested: * EggSMClient::quit_requested:
* @client: the client * @client: the client
* *
* Emitted when the session manager requests that the application * Emitted when the session manager requests that the application
* exit (generally because the user is logging out). The application * exit (generally because the user is logging out). The application
* should decide whether or not it is willing to quit (perhaps after * should decide whether or not it is willing to quit (perhaps after
* asking the user what to do with documents that have unsaved * asking the user what to do with documents that have unsaved
* changes) and then call egg_sm_client_will_quit(), passing %TRUE * changes) and then call egg_sm_client_will_quit(), passing %TRUE
* or %FALSE to give its answer to the session manager. (It does not * or %FALSE to give its answer to the session manager. (It does not
* need to give an answer before returning from the signal handler; * need to give an answer before returning from the signal handler;
* it can interact with the user asynchronously and then give its * it can interact with the user asynchronously and then give its
* answer later on.) If the application does not connect to this * answer later on.) If the application does not connect to this
* signal, then #EggSMClient will automatically return %TRUE on its * signal, then #EggSMClient will automatically return %TRUE on its
* behalf. * behalf.
* *
* The application should not save its session state as part of * The application should not save its session state as part of
* handling this signal; if the user has requested that the session * handling this signal; if the user has requested that the session
* be saved when logging out, then ::save_state will be emitted * be saved when logging out, then ::save_state will be emitted
* separately. * separately.
* *
* If the application agrees to quit, it should then wait for either * If the application agrees to quit, it should then wait for either
* the ::quit_cancelled or ::quit signals to be emitted. * the ::quit_cancelled or ::quit signals to be emitted.
**/ **/
signals[QUIT_REQUESTED] = signals[QUIT_REQUESTED] =
g_signal_new ("quit_requested", g_signal_new ("quit_requested",
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, quit_requested), G_STRUCT_OFFSET (EggSMClientClass, quit_requested),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__VOID, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, G_TYPE_NONE,
0); 0);
/** /**
* EggSMClient::quit_cancelled: * EggSMClient::quit_cancelled:
* @client: the client * @client: the client
* *
* Emitted when the session manager decides to cancel a logout after * Emitted when the session manager decides to cancel a logout after
* the application has already agreed to quit. After receiving this * the application has already agreed to quit. After receiving this
* signal, the application can go back to what it was doing before * signal, the application can go back to what it was doing before
* receiving the ::quit_requested signal. * receiving the ::quit_requested signal.
**/ **/
signals[QUIT_CANCELLED] = signals[QUIT_CANCELLED] =
g_signal_new ("quit_cancelled", g_signal_new ("quit_cancelled",
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled), G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__VOID, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, G_TYPE_NONE,
0); 0);
/** /**
* EggSMClient::quit: * EggSMClient::quit:
* @client: the client * @client: the client
* *
* Emitted when the session manager wants the application to quit * Emitted when the session manager wants the application to quit
* (generally because the user is logging out). The application * (generally because the user is logging out). The application
* should exit as soon as possible after receiving this signal; if * should exit as soon as possible after receiving this signal; if
* it does not, the session manager may choose to forcibly kill it. * it does not, the session manager may choose to forcibly kill it.
* *
* Normally a GUI application would only be sent a ::quit if it * Normally a GUI application would only be sent a ::quit if it
* agreed to quit in response to a ::quit_requested signal. However, * agreed to quit in response to a ::quit_requested signal. However,
* this is not guaranteed; in some situations the session manager * this is not guaranteed; in some situations the session manager
* may decide to end the session without giving applications a * may decide to end the session without giving applications a
* chance to object. * chance to object.
**/ **/
signals[QUIT] = signals[QUIT] =
g_signal_new ("quit", g_signal_new ("quit",
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, quit), G_STRUCT_OFFSET (EggSMClientClass, quit),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__VOID, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, G_TYPE_NONE,
0); 0);
} }
static gboolean sm_client_disable = FALSE; static gboolean sm_client_disable = FALSE;
@ -182,29 +184,29 @@ static char *sm_config_prefix = NULL;
static gboolean static gboolean
sm_client_post_parse_func (GOptionContext *context, sm_client_post_parse_func (GOptionContext *context,
GOptionGroup *group, GOptionGroup *group,
gpointer data, gpointer data,
GError **error) GError **error)
{ {
EggSMClient *client = egg_sm_client_get (); EggSMClient *client = egg_sm_client_get ();
if (sm_client_id == NULL) if (sm_client_id == NULL)
{ {
const gchar *desktop_autostart_id; const gchar *desktop_autostart_id;
desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID"); desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
if (desktop_autostart_id != NULL) if (desktop_autostart_id != NULL)
sm_client_id = g_strdup (desktop_autostart_id); sm_client_id = g_strdup (desktop_autostart_id);
} }
/* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
* use the same client id. */ * use the same client id. */
g_unsetenv ("DESKTOP_AUTOSTART_ID"); g_unsetenv ("DESKTOP_AUTOSTART_ID");
if (EGG_SM_CLIENT_GET_CLASS (client)->startup) if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id); EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
return TRUE; return TRUE;
} }
/** /**
@ -219,43 +221,54 @@ sm_client_post_parse_func (GOptionContext *context,
GOptionGroup * GOptionGroup *
egg_sm_client_get_option_group (void) egg_sm_client_get_option_group (void)
{ {
const GOptionEntry entries[] = { const GOptionEntry entries[] =
{ "sm-client-disable", 0, 0, {
G_OPTION_ARG_NONE, &sm_client_disable, {
N_("Disable connection to session manager"), NULL }, "sm-client-disable", 0, 0,
{ "sm-client-state-file", 0, 0, G_OPTION_ARG_NONE, &sm_client_disable,
G_OPTION_ARG_FILENAME, &sm_client_state_file, N_("Disable connection to session manager"), NULL
N_("Specify file containing saved configuration"), N_("FILE") }, },
{ "sm-client-id", 0, 0, {
G_OPTION_ARG_STRING, &sm_client_id, "sm-client-state-file", 0, 0,
N_("Specify session management ID"), N_("ID") }, G_OPTION_ARG_FILENAME, &sm_client_state_file,
/* MateClient compatibility option */ N_("Specify file containing saved configuration"), N_("FILE")
{ "sm-disable", 0, G_OPTION_FLAG_HIDDEN, },
G_OPTION_ARG_NONE, &sm_client_disable, {
NULL, NULL }, "sm-client-id", 0, 0,
/* MateClient compatibility option. This is a dummy option that only G_OPTION_ARG_STRING, &sm_client_id,
* exists so that sessions saved by apps with MateClient can be restored N_("Specify session management ID"), N_("ID")
* later when they've switched to EggSMClient. See bug #575308. },
*/ /* MateClient compatibility option */
{ "sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN, {
G_OPTION_ARG_STRING, &sm_config_prefix, "sm-disable", 0, G_OPTION_FLAG_HIDDEN,
NULL, NULL }, G_OPTION_ARG_NONE, &sm_client_disable,
{ NULL } NULL, NULL
}; },
GOptionGroup *group; /* MateClient compatibility option. This is a dummy option that only
* exists so that sessions saved by apps with MateClient can be restored
* later when they've switched to EggSMClient. See bug #575308.
*/
{
"sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_STRING, &sm_config_prefix,
NULL, NULL
},
{ NULL }
};
GOptionGroup *group;
/* Use our own debug handler for the "EggSMClient" domain. */ /* Use our own debug handler for the "EggSMClient" domain. */
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
egg_sm_client_debug_handler, NULL); egg_sm_client_debug_handler, NULL);
group = g_option_group_new ("sm-client", group = g_option_group_new ("sm-client",
_("Session management options:"), _("Session management options:"),
_("Show session management options"), _("Show session management options"),
NULL, NULL); NULL, NULL);
g_option_group_add_entries (group, entries); g_option_group_add_entries (group, entries);
g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func); g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func);
return group; return group;
} }
/** /**
@ -282,7 +295,7 @@ egg_sm_client_get_option_group (void)
void void
egg_sm_client_set_mode (EggSMClientMode mode) egg_sm_client_set_mode (EggSMClientMode mode)
{ {
global_client_mode = mode; global_client_mode = mode;
} }
/** /**
@ -296,7 +309,7 @@ egg_sm_client_set_mode (EggSMClientMode mode)
EggSMClientMode EggSMClientMode
egg_sm_client_get_mode (void) egg_sm_client_get_mode (void)
{ {
return global_client_mode; return global_client_mode;
} }
/** /**
@ -315,38 +328,38 @@ egg_sm_client_get_mode (void)
EggSMClient * EggSMClient *
egg_sm_client_get (void) egg_sm_client_get (void)
{ {
if (!global_client) if (!global_client)
{
if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
!sm_client_disable)
{ {
if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
!sm_client_disable)
{
#if defined (GDK_WINDOWING_WIN32) #if defined (GDK_WINDOWING_WIN32)
global_client = egg_sm_client_win32_new (); global_client = egg_sm_client_win32_new ();
#elif defined (GDK_WINDOWING_QUARTZ) #elif defined (GDK_WINDOWING_QUARTZ)
global_client = egg_sm_client_osx_new (); global_client = egg_sm_client_osx_new ();
#else #else
/* If both D-Bus and XSMP are compiled in, try XSMP first /* If both D-Bus and XSMP are compiled in, try XSMP first
* (since it supports state saving) and fall back to D-Bus * (since it supports state saving) and fall back to D-Bus
* if XSMP isn't available. * if XSMP isn't available.
*/ */
# ifdef EGG_SM_CLIENT_BACKEND_XSMP # ifdef EGG_SM_CLIENT_BACKEND_XSMP
global_client = egg_sm_client_xsmp_new (); global_client = egg_sm_client_xsmp_new ();
# endif # endif
# ifdef EGG_SM_CLIENT_BACKEND_DBUS # ifdef EGG_SM_CLIENT_BACKEND_DBUS
if (!global_client) if (!global_client)
global_client = egg_sm_client_dbus_new (); global_client = egg_sm_client_dbus_new ();
# endif # endif
#endif #endif
}
/* Fallback: create a dummy client, so that callers don't have
* to worry about a %NULL return value.
*/
if (!global_client)
global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL);
} }
/* Fallback: create a dummy client, so that callers don't have return global_client;
* to worry about a %NULL return value.
*/
if (!global_client)
global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL);
}
return global_client;
} }
/** /**
@ -363,9 +376,9 @@ egg_sm_client_get (void)
gboolean gboolean
egg_sm_client_is_resumed (EggSMClient *client) egg_sm_client_is_resumed (EggSMClient *client)
{ {
g_return_val_if_fail (client == global_client, FALSE); g_return_val_if_fail (client == global_client, FALSE);
return sm_client_state_file != NULL; return sm_client_state_file != NULL;
} }
/** /**
@ -390,34 +403,34 @@ egg_sm_client_is_resumed (EggSMClient *client)
GKeyFile * GKeyFile *
egg_sm_client_get_state_file (EggSMClient *client) egg_sm_client_get_state_file (EggSMClient *client)
{ {
EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client); EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client);
char *state_file_path; char *state_file_path;
GError *err = NULL; GError *err = NULL;
g_return_val_if_fail (client == global_client, NULL); g_return_val_if_fail (client == global_client, NULL);
if (!sm_client_state_file) if (!sm_client_state_file)
return NULL; return NULL;
if (priv->state_file) if (priv->state_file)
return priv->state_file; return priv->state_file;
if (!strncmp (sm_client_state_file, "file://", 7)) if (!strncmp (sm_client_state_file, "file://", 7))
state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL); state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL);
else else
state_file_path = g_strdup (sm_client_state_file); state_file_path = g_strdup (sm_client_state_file);
priv->state_file = g_key_file_new (); priv->state_file = g_key_file_new ();
if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err)) if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err))
{ {
g_warning ("Could not load SM state file '%s': %s", g_warning ("Could not load SM state file '%s': %s",
sm_client_state_file, err->message); sm_client_state_file, err->message);
g_clear_error (&err); g_clear_error (&err);
g_key_file_free (priv->state_file); g_key_file_free (priv->state_file);
priv->state_file = NULL; priv->state_file = NULL;
} }
g_free (state_file_path); g_free (state_file_path);
return priv->state_file; return priv->state_file;
} }
/** /**
@ -435,13 +448,13 @@ egg_sm_client_get_state_file (EggSMClient *client)
**/ **/
void void
egg_sm_client_set_restart_command (EggSMClient *client, egg_sm_client_set_restart_command (EggSMClient *client,
int argc, int argc,
const char **argv) const char **argv)
{ {
g_return_if_fail (EGG_IS_SM_CLIENT (client)); g_return_if_fail (EGG_IS_SM_CLIENT (client));
if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command) if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command)
EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv); EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv);
} }
/** /**
@ -451,18 +464,18 @@ egg_sm_client_set_restart_command (EggSMClient *client,
* @argv: argument vector * @argv: argument vector
* *
* Sets the command used to discard a custom state file if using * Sets the command used to discard a custom state file if using
* egg_sm_client_set_restart_command(), which must be called before * egg_sm_client_set_restart_command(), which must be called before
* using this function. * using this function.
**/ **/
void void
egg_sm_client_set_discard_command (EggSMClient *client, egg_sm_client_set_discard_command (EggSMClient *client,
int argc, int argc,
const char **argv) const char **argv)
{ {
g_return_if_fail (EGG_IS_SM_CLIENT (client)); g_return_if_fail (EGG_IS_SM_CLIENT (client));
if (EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command) if (EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command)
EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command (client, argc, argv); EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command (client, argc, argv);
} }
/** /**
@ -485,12 +498,12 @@ egg_sm_client_set_discard_command (EggSMClient *client,
**/ **/
void void
egg_sm_client_will_quit (EggSMClient *client, egg_sm_client_will_quit (EggSMClient *client,
gboolean will_quit) gboolean will_quit)
{ {
g_return_if_fail (EGG_IS_SM_CLIENT (client)); g_return_if_fail (EGG_IS_SM_CLIENT (client));
if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit) if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit)
EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit); EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit);
} }
/** /**
@ -511,19 +524,19 @@ egg_sm_client_will_quit (EggSMClient *client,
**/ **/
gboolean gboolean
egg_sm_client_end_session (EggSMClientEndStyle style, egg_sm_client_end_session (EggSMClientEndStyle style,
gboolean request_confirmation) gboolean request_confirmation)
{ {
EggSMClient *client = egg_sm_client_get (); EggSMClient *client = egg_sm_client_get ();
g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE); g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE);
if (EGG_SM_CLIENT_GET_CLASS (client)->end_session) if (EGG_SM_CLIENT_GET_CLASS (client)->end_session)
{ {
return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style, return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style,
request_confirmation); request_confirmation);
} }
else else
return FALSE; return FALSE;
} }
/* Signal-emitting callbacks from platform-specific code */ /* Signal-emitting callbacks from platform-specific code */
@ -531,80 +544,80 @@ egg_sm_client_end_session (EggSMClientEndStyle style,
GKeyFile * GKeyFile *
egg_sm_client_save_state (EggSMClient *client) egg_sm_client_save_state (EggSMClient *client)
{ {
GKeyFile *state_file; GKeyFile *state_file;
char *group; char *group;
g_return_val_if_fail (client == global_client, NULL); g_return_val_if_fail (client == global_client, NULL);
state_file = g_key_file_new (); state_file = g_key_file_new ();
g_debug ("Emitting save_state"); g_debug ("Emitting save_state");
g_signal_emit (client, signals[SAVE_STATE], 0, state_file); g_signal_emit (client, signals[SAVE_STATE], 0, state_file);
g_debug ("Done emitting save_state"); g_debug ("Done emitting save_state");
group = g_key_file_get_start_group (state_file); group = g_key_file_get_start_group (state_file);
if (group) if (group)
{ {
g_free (group); g_free (group);
return state_file; return state_file;
} }
else else
{ {
g_key_file_free (state_file); g_key_file_free (state_file);
return NULL; return NULL;
} }
} }
void void
egg_sm_client_quit_requested (EggSMClient *client) egg_sm_client_quit_requested (EggSMClient *client)
{ {
g_return_if_fail (client == global_client); g_return_if_fail (client == global_client);
if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE)) if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE))
{ {
g_debug ("Not emitting quit_requested because no one is listening"); g_debug ("Not emitting quit_requested because no one is listening");
egg_sm_client_will_quit (client, TRUE); egg_sm_client_will_quit (client, TRUE);
return; return;
} }
g_debug ("Emitting quit_requested"); g_debug ("Emitting quit_requested");
g_signal_emit (client, signals[QUIT_REQUESTED], 0); g_signal_emit (client, signals[QUIT_REQUESTED], 0);
g_debug ("Done emitting quit_requested"); g_debug ("Done emitting quit_requested");
} }
void void
egg_sm_client_quit_cancelled (EggSMClient *client) egg_sm_client_quit_cancelled (EggSMClient *client)
{ {
g_return_if_fail (client == global_client); g_return_if_fail (client == global_client);
g_debug ("Emitting quit_cancelled"); g_debug ("Emitting quit_cancelled");
g_signal_emit (client, signals[QUIT_CANCELLED], 0); g_signal_emit (client, signals[QUIT_CANCELLED], 0);
g_debug ("Done emitting quit_cancelled"); g_debug ("Done emitting quit_cancelled");
} }
void void
egg_sm_client_quit (EggSMClient *client) egg_sm_client_quit (EggSMClient *client)
{ {
g_return_if_fail (client == global_client); g_return_if_fail (client == global_client);
g_debug ("Emitting quit"); g_debug ("Emitting quit");
g_signal_emit (client, signals[QUIT], 0); g_signal_emit (client, signals[QUIT], 0);
g_debug ("Done emitting quit"); g_debug ("Done emitting quit");
/* FIXME: should we just call gtk_main_quit() here? */ /* FIXME: should we just call gtk_main_quit() here? */
} }
static void static void
egg_sm_client_debug_handler (const char *log_domain, egg_sm_client_debug_handler (const char *log_domain,
GLogLevelFlags log_level, GLogLevelFlags log_level,
const char *message, const char *message,
gpointer user_data) gpointer user_data)
{ {
static int debug = -1; static int debug = -1;
if (debug < 0) if (debug < 0)
debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL); debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL);
if (debug) if (debug)
g_log_default_handler (log_domain, log_level, message, NULL); g_log_default_handler (log_domain, log_level, message, NULL);
} }

View File

@ -35,57 +35,59 @@ typedef struct _EggSMClient EggSMClient;
typedef struct _EggSMClientClass EggSMClientClass; typedef struct _EggSMClientClass EggSMClientClass;
typedef struct _EggSMClientPrivate EggSMClientPrivate; typedef struct _EggSMClientPrivate EggSMClientPrivate;
typedef enum { typedef enum
EGG_SM_CLIENT_END_SESSION_DEFAULT, {
EGG_SM_CLIENT_LOGOUT, EGG_SM_CLIENT_END_SESSION_DEFAULT,
EGG_SM_CLIENT_REBOOT, EGG_SM_CLIENT_LOGOUT,
EGG_SM_CLIENT_SHUTDOWN EGG_SM_CLIENT_REBOOT,
EGG_SM_CLIENT_SHUTDOWN
} EggSMClientEndStyle; } EggSMClientEndStyle;
typedef enum { typedef enum
EGG_SM_CLIENT_MODE_DISABLED, {
EGG_SM_CLIENT_MODE_NO_RESTART, EGG_SM_CLIENT_MODE_DISABLED,
EGG_SM_CLIENT_MODE_NORMAL EGG_SM_CLIENT_MODE_NO_RESTART,
EGG_SM_CLIENT_MODE_NORMAL
} EggSMClientMode; } EggSMClientMode;
struct _EggSMClient struct _EggSMClient
{ {
GObject parent; GObject parent;
}; };
struct _EggSMClientClass struct _EggSMClientClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
/* signals */ /* signals */
void (*save_state) (EggSMClient *client, void (*save_state) (EggSMClient *client,
GKeyFile *state_file); GKeyFile *state_file);
void (*quit_requested) (EggSMClient *client); void (*quit_requested) (EggSMClient *client);
void (*quit_cancelled) (EggSMClient *client); void (*quit_cancelled) (EggSMClient *client);
void (*quit) (EggSMClient *client); void (*quit) (EggSMClient *client);
/* virtual methods */ /* virtual methods */
void (*startup) (EggSMClient *client, void (*startup) (EggSMClient *client,
const char *client_id); const char *client_id);
void (*set_restart_command) (EggSMClient *client, void (*set_restart_command) (EggSMClient *client,
int argc, int argc,
const char **argv); const char **argv);
void (*set_discard_command) (EggSMClient *client, void (*set_discard_command) (EggSMClient *client,
int argc, int argc,
const char **argv); const char **argv);
void (*will_quit) (EggSMClient *client, void (*will_quit) (EggSMClient *client,
gboolean will_quit); gboolean will_quit);
gboolean (*end_session) (EggSMClient *client, gboolean (*end_session) (EggSMClient *client,
EggSMClientEndStyle style, EggSMClientEndStyle style,
gboolean request_confirmation); gboolean request_confirmation);
/* Padding for future expansion */ /* Padding for future expansion */
void (*_egg_reserved1) (void); void (*_egg_reserved1) (void);
void (*_egg_reserved2) (void); void (*_egg_reserved2) (void);
void (*_egg_reserved3) (void); void (*_egg_reserved3) (void);
void (*_egg_reserved4) (void); void (*_egg_reserved4) (void);
}; };
GType egg_sm_client_get_type (void) G_GNUC_CONST; GType egg_sm_client_get_type (void) G_GNUC_CONST;
@ -103,19 +105,19 @@ GKeyFile *egg_sm_client_get_state_file (EggSMClient *client);
/* Alternate means of saving state */ /* Alternate means of saving state */
void egg_sm_client_set_restart_command (EggSMClient *client, void egg_sm_client_set_restart_command (EggSMClient *client,
int argc, int argc,
const char **argv); const char **argv);
void egg_sm_client_set_discard_command (EggSMClient *client, void egg_sm_client_set_discard_command (EggSMClient *client,
int argc, int argc,
const char **argv); const char **argv);
/* Handling "quit_requested" signal */ /* Handling "quit_requested" signal */
void egg_sm_client_will_quit (EggSMClient *client, void egg_sm_client_will_quit (EggSMClient *client,
gboolean will_quit); gboolean will_quit);
/* Initiate a logout/reboot/shutdown */ /* Initiate a logout/reboot/shutdown */
gboolean egg_sm_client_end_session (EggSMClientEndStyle style, gboolean egg_sm_client_end_session (EggSMClientEndStyle style,
gboolean request_confirmation); gboolean request_confirmation);
G_END_DECLS G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@ -30,199 +30,200 @@
#define SKEY_PREFIX "s/key " #define SKEY_PREFIX "s/key "
#define OTP_PREFIX "otp-" #define OTP_PREFIX "otp-"
typedef struct { typedef struct
TerminalScreen *screen; {
char *seed; TerminalScreen *screen;
int seq; char *seed;
int hash; int seq;
int hash;
} SkeyData; } SkeyData;
static void static void
skey_data_free (SkeyData *data) skey_data_free (SkeyData *data)
{ {
g_free (data->seed); g_free (data->seed);
g_free (data); g_free (data);
} }
static gboolean static gboolean
extract_seq_and_seed (const gchar *skey_match, extract_seq_and_seed (const gchar *skey_match,
gint *seq, gint *seq,
gchar **seed) gchar **seed)
{ {
gchar *end_ptr = NULL; gchar *end_ptr = NULL;
/* FIXME: use g_ascii_strtoll */ /* FIXME: use g_ascii_strtoll */
*seq = strtol (skey_match + strlen (SKEY_PREFIX), &end_ptr, 0); *seq = strtol (skey_match + strlen (SKEY_PREFIX), &end_ptr, 0);
if (end_ptr == NULL || *end_ptr == '\000') if (end_ptr == NULL || *end_ptr == '\000')
return FALSE; return FALSE;
*seed = g_strdup (end_ptr + 1); *seed = g_strdup (end_ptr + 1);
return TRUE; return TRUE;
} }
static gboolean static gboolean
extract_hash_seq_and_seed (const gchar *otp_match, extract_hash_seq_and_seed (const gchar *otp_match,
gint *hash, gint *hash,
gint *seq, gint *seq,
gchar **seed) gchar **seed)
{ {
gchar *end_ptr = NULL; gchar *end_ptr = NULL;
const gchar *p = otp_match + strlen (OTP_PREFIX); const gchar *p = otp_match + strlen (OTP_PREFIX);
gint len = 3; gint len = 3;
if (strncmp (p, "md4", 3) == 0) if (strncmp (p, "md4", 3) == 0)
*hash = MD4; *hash = MD4;
else if (strncmp (p, "md5", 3) == 0) else if (strncmp (p, "md5", 3) == 0)
*hash = MD5; *hash = MD5;
else if (strncmp (p, "sha1", 4) == 0) else if (strncmp (p, "sha1", 4) == 0)
{ {
*hash = SHA1; *hash = SHA1;
len++; len++;
} }
else else
return FALSE; return FALSE;
p += len; p += len;
/* RFC mandates the following skipping */ /* RFC mandates the following skipping */
while (*p == ' ' || *p == '\t') while (*p == ' ' || *p == '\t')
{ {
if (*p == '\0') if (*p == '\0')
return FALSE; return FALSE;
p++; p++;
} }
/* FIXME: use g_ascii_strtoll */ /* FIXME: use g_ascii_strtoll */
*seq = strtol (p, &end_ptr, 0); *seq = strtol (p, &end_ptr, 0);
if (end_ptr == NULL || *end_ptr == '\000') if (end_ptr == NULL || *end_ptr == '\000')
return FALSE; return FALSE;
p = end_ptr; p = end_ptr;
while (*p == ' ' || *p == '\t') while (*p == ' ' || *p == '\t')
{ {
if (*p == '\0') if (*p == '\0')
return FALSE; return FALSE;
p++; p++;
} }
*seed = g_strdup (p); *seed = g_strdup (p);
return TRUE; return TRUE;
} }
static void static void
skey_challenge_response_cb (GtkWidget *dialog, skey_challenge_response_cb (GtkWidget *dialog,
int response_id, int response_id,
SkeyData *data) SkeyData *data)
{ {
if (response_id == GTK_RESPONSE_OK) if (response_id == GTK_RESPONSE_OK)
{
GtkWidget *entry;
const char *password;
char *response;
entry = g_object_get_data (G_OBJECT (dialog), "skey-entry");
password = gtk_entry_get_text (GTK_ENTRY (entry));
/* FIXME: fix skey to use g_malloc */
response = skey (data->hash, data->seq, data->seed, password);
if (response)
{ {
VteTerminal *vte_terminal = VTE_TERMINAL (data->screen); GtkWidget *entry;
static const char newline[2] = "\n"; const char *password;
char *response;
vte_terminal_feed_child (vte_terminal, response, strlen (response)); entry = g_object_get_data (G_OBJECT (dialog), "skey-entry");
vte_terminal_feed_child (vte_terminal, newline, strlen (newline)); password = gtk_entry_get_text (GTK_ENTRY (entry));
free (response);
/* FIXME: fix skey to use g_malloc */
response = skey (data->hash, data->seq, data->seed, password);
if (response)
{
VteTerminal *vte_terminal = VTE_TERMINAL (data->screen);
static const char newline[2] = "\n";
vte_terminal_feed_child (vte_terminal, response, strlen (response));
vte_terminal_feed_child (vte_terminal, newline, strlen (newline));
free (response);
}
} }
}
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
} }
void void
terminal_skey_do_popup (GtkWindow *window, terminal_skey_do_popup (GtkWindow *window,
TerminalScreen *screen, TerminalScreen *screen,
const gchar *skey_match) const gchar *skey_match)
{ {
GtkWidget *dialog, *label, *entry, *ok_button; GtkWidget *dialog, *label, *entry, *ok_button;
char *title_text; char *title_text;
char *seed; char *seed;
int seq; int seq;
int hash = MD5; int hash = MD5;
SkeyData *data; SkeyData *data;
if (strncmp (SKEY_PREFIX, skey_match, strlen (SKEY_PREFIX)) == 0) if (strncmp (SKEY_PREFIX, skey_match, strlen (SKEY_PREFIX)) == 0)
{
if (!extract_seq_and_seed (skey_match, &seq, &seed))
{ {
terminal_util_show_error_dialog (window, NULL, NULL, if (!extract_seq_and_seed (skey_match, &seq, &seed))
_("The text you clicked on doesn't " {
"seem to be a valid S/Key " terminal_util_show_error_dialog (window, NULL, NULL,
"challenge.")); _("The text you clicked on doesn't "
return; "seem to be a valid S/Key "
"challenge."));
return;
}
} }
} else
else
{
if (!extract_hash_seq_and_seed (skey_match, &hash, &seq, &seed))
{ {
terminal_util_show_error_dialog (window, NULL, NULL, if (!extract_hash_seq_and_seed (skey_match, &hash, &seq, &seed))
_("The text you clicked on doesn't " {
"seem to be a valid OTP " terminal_util_show_error_dialog (window, NULL, NULL,
"challenge.")); _("The text you clicked on doesn't "
return; "seem to be a valid OTP "
"challenge."));
return;
}
} }
}
if (!terminal_util_load_builder_file ("skey-challenge.ui", if (!terminal_util_load_builder_file ("skey-challenge.ui",
"skey-dialog", &dialog, "skey-dialog", &dialog,
"skey-entry", &entry, "skey-entry", &entry,
"text-label", &label, "text-label", &label,
"skey-ok-button", &ok_button, "skey-ok-button", &ok_button,
NULL)) NULL))
{ {
g_free (seed); g_free (seed);
return; return;
} }
title_text = g_strdup_printf ("<big><b>%s</b></big>", title_text = g_strdup_printf ("<big><b>%s</b></big>",
gtk_label_get_text (GTK_LABEL (label))); gtk_label_get_text (GTK_LABEL (label)));
gtk_label_set_label (GTK_LABEL (label), title_text); gtk_label_set_label (GTK_LABEL (label), title_text);
g_free (title_text); g_free (title_text);
g_object_set_data (G_OBJECT (dialog), "skey-entry", entry); g_object_set_data (G_OBJECT (dialog), "skey-entry", entry);
gtk_widget_grab_focus (entry); gtk_widget_grab_focus (entry);
gtk_widget_grab_default (ok_button); gtk_widget_grab_default (ok_button);
gtk_entry_set_text (GTK_ENTRY (entry), ""); gtk_entry_set_text (GTK_ENTRY (entry), "");
gtk_window_set_transient_for (GTK_WINDOW (dialog), window); gtk_window_set_transient_for (GTK_WINDOW (dialog), window);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE); gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK, GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL, GTK_RESPONSE_CANCEL,
-1); -1);
/* FIXME: make this dialogue close if the screen closes! */ /* FIXME: make this dialogue close if the screen closes! */
data = g_new (SkeyData, 1); data = g_new (SkeyData, 1);
data->hash = hash; data->hash = hash;
data->seq = seq; data->seq = seq;
data->seed = seed; data->seed = seed;
data->screen = screen; data->screen = screen;
g_signal_connect_data (dialog, "response", g_signal_connect_data (dialog, "response",
G_CALLBACK (skey_challenge_response_cb), G_CALLBACK (skey_challenge_response_cb),
data, (GClosureNotify) skey_data_free, 0); data, (GClosureNotify) skey_data_free, 0);
g_signal_connect (dialog, "delete-event", g_signal_connect (dialog, "delete-event",
G_CALLBACK (terminal_util_dialog_response_on_delete), NULL); G_CALLBACK (terminal_util_dialog_response_on_delete), NULL);
gtk_window_present (GTK_WINDOW (dialog)); gtk_window_present (GTK_WINDOW (dialog));
} }

View File

@ -28,7 +28,7 @@ G_BEGIN_DECLS
void terminal_skey_do_popup (GtkWindow *window, void terminal_skey_do_popup (GtkWindow *window,
TerminalScreen *screen, TerminalScreen *screen,
const gchar *skey_match); const gchar *skey_match);
G_END_DECLS G_END_DECLS

View File

@ -16,228 +16,228 @@ static guint32 extract (char *s, int start, int length);
/* Dictionary for integer-word translations */ /* Dictionary for integer-word translations */
static const char Wp[2048][4] = { "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", static const char Wp[2048][4] = { "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA", "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
"AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK", "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
"ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE", "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
"AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM", "AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
"BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO", "BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
"BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT", "BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
"BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT", "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY", "CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
"CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN", "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
"DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG", "DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
"DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB", "DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO", "DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
"ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE", "ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
"EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW", "EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
"FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", "FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP", "FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
"GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO", "GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
"GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD", "GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
"HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM", "HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT", "HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",
"HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE", "HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE",
"HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL", "HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL",
"INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS", "INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS",
"IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG",
"JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY", "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY",
"KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC",
"LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG", "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG",
"LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO",
"LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE", "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE",
"MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY",
"ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB", "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB",
"MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM",
"MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE", "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE",
"NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON",
"NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK",
"OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK",
"OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR", "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR",
"OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL",
"PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN", "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN",
"PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY",
"PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG", "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG",
"PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW",
"RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO", "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO",
"RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE",
"RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN", "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN",
"SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW",
"SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY", "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY",
"SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB",
"SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP",
"TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM",
"TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW", "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW",
"TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US",
"USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY", "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY",
"WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK",
"WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA", "WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA",
"YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE",
"ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR",
"AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR",
"AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO", "AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO",
"ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", "ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS",
"AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB",
"ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", "ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS",
"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW", "ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW",
"AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT", "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT",
"BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE",
"BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE", "BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE",
"BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK", "BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK",
"BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER",
"BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", "BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT",
"BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE",
"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT", "BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT",
"BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR",
"BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL", "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL",
"BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", "BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN",
"BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE",
"BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", "BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN",
"BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", "BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF",
"BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN", "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN",
"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY", "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY",
"CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE",
"CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK", "CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK",
"CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT",
"CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB",
"CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", "CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY",
"CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", "CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK",
"COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA", "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA",
"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT", "COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT",
"CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG", "CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG",
"CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF", "CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF",
"CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS", "CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS",
"DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK", "DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK",
"DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", "DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS",
"DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", "DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM",
"DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE", "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE",
"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC", "DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC",
"DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME", "DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME",
"DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE", "DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE",
"DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM", "DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM",
"DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE",
"DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", "DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST",
"EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA", "EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA",
"EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS", "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS",
"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE", "ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE",
"FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST", "FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST",
"FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT", "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT",
"FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM", "FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM",
"FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", "FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS",
"FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", "FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW",
"FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY", "FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY",
"FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD", "FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD",
"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU", "FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU",
"FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL", "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL",
"FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL", "FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL",
"GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB", "GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB",
"GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD",
"GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", "GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT",
"GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", "GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB",
"GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT", "GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT",
"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE", "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE",
"GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW", "GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW",
"GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL", "GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL",
"GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK", "GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK",
"HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG", "HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG",
"HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE", "HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE",
"HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT", "HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT",
"HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB", "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB",
"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH", "HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH",
"HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO", "HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO",
"HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK", "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK",
"HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE", "HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE",
"HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO",
"HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", "HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE",
"HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO", "HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO",
"IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM", "IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM",
"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF", "IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF",
"JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS", "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS",
"JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD", "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD",
"JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", "JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO",
"JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE", "JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE",
"KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", "KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL",
"KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT", "KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT",
"KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE", "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE",
"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB", "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB",
"LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE", "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE",
"LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN",
"LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", "LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK",
"LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", "LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES",
"LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB",
"LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", "LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE",
"LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA", "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA",
"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS", "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS",
"LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU",
"LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN", "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN",
"LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", "LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE",
"MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", "MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE",
"MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE", "MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE",
"MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", "MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET",
"MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE", "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE",
"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE", "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE",
"MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN", "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN",
"MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK",
"MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", "MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS",
"MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", "MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL",
"MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", "MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL",
"NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", "NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT",
"NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS", "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS",
"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE", "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE",
"NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN",
"NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO", "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO",
"OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", "OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN",
"OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO",
"OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", "OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",
"OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", "OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE",
"RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE", "RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE",
"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF", "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF",
"REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE", "REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE",
"RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE", "RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE",
"RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL", "RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL",
"ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE",
"ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", "ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY",
"RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH", "RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH",
"RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL", "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL",
"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA", "SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA",
"SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM",
"SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL", "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL",
"SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED", "SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED",
"SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK",
"SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", "SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE",
"SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID", "SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID",
"SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW", "SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW",
"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM", "SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM",
"SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK",
"SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG", "SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG",
"SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", "SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG",
"STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN", "STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN",
"SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", "SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF",
"SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK", "SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK",
"TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE", "TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE",
"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL", "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL",
"TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE", "TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE",
"THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE", "THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE",
"TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE", "TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE",
"TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE",
"TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", "TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR",
"TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", "TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM",
"TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT", "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT",
"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT", "TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT",
"ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN", "ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN",
"VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND", "VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND",
"VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID", "VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID",
"VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE", "VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE",
"WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM", "WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM",
"WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS", "WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS",
"WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL", "WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL",
"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN", "WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN",
"WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE", "WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE",
"WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT", "WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT",
"WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT", "WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT",
"WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", "WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH",
"YEAR", "YELL", "YOGA", "YOKE" "YEAR", "YELL", "YOGA", "YOKE"
}; };
/* /*
* Encode 8 bytes in 'c' as a string of English words. * Encode 8 bytes in 'c' as a string of English words.
@ -246,31 +246,31 @@ static const char Wp[2048][4] = { "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
char *btoe(unsigned char *md) char *btoe(unsigned char *md)
{ {
char cp[9]; /* 64 + 2 = 66 bits */ char cp[9]; /* 64 + 2 = 66 bits */
int p, i; int p, i;
static int buf[BUFSIZ]; static int buf[BUFSIZ];
char *engout = (char *)buf; char *engout = (char *)buf;
memcpy(cp, md, SKEY_SIZE); memcpy(cp, md, SKEY_SIZE);
/* compute parity */ /* compute parity */
for(p = 0, i = 0; i < 64; i += 2) for(p = 0, i = 0; i < 64; i += 2)
p += extract(cp, i, 2); p += extract(cp, i, 2);
cp[8] = (char)p << 6; cp[8] = (char)p << 6;
/* now 66 bits */ /* now 66 bits */
engout[0] = '\0'; engout[0] = '\0';
strncat(engout, &Wp[extract(cp, 0, 11)][0], 4); strncat(engout, &Wp[extract(cp, 0, 11)][0], 4);
strcat (engout," "); strcat (engout," ");
strncat(engout, &Wp[extract(cp, 11, 11)][0], 4); strncat(engout, &Wp[extract(cp, 11, 11)][0], 4);
strcat (engout," "); strcat (engout," ");
strncat(engout, &Wp[extract(cp, 22, 11)][0], 4); strncat(engout, &Wp[extract(cp, 22, 11)][0], 4);
strcat (engout," "); strcat (engout," ");
strncat(engout, &Wp[extract(cp, 33, 11)][0], 4); strncat(engout, &Wp[extract(cp, 33, 11)][0], 4);
strcat (engout," "); strcat (engout," ");
strncat(engout, &Wp[extract(cp, 44, 11)][0], 4); strncat(engout, &Wp[extract(cp, 44, 11)][0], 4);
strcat (engout," "); strcat (engout," ");
strncat(engout, &Wp[extract(cp, 55, 11)][0], 4); strncat(engout, &Wp[extract(cp, 55, 11)][0], 4);
return (engout); return (engout);
} }
@ -282,23 +282,23 @@ char *btoe(unsigned char *md)
static guint32 extract(char *s, int start, int length) static guint32 extract(char *s, int start, int length)
{ {
guint8 cl; guint8 cl;
guint8 cc; guint8 cc;
guint8 cr; guint8 cr;
guint32 x; guint32 x;
/* 66 = 11 x 6 */ /* 66 = 11 x 6 */
g_assert(length >= 0);
g_assert(length <= 11);
g_assert(start >= 0);
g_assert(start + length <= 66);
cl = s[start/8]; g_assert(length >= 0);
cc = s[start/8 + 1]; g_assert(length <= 11);
cr = s[start/8 + 2]; g_assert(start >= 0);
x = (guint32) ((((cl << 8) | cc) << 8) | cr); /* 24 bits */ g_assert(start + length <= 66);
x = x >> (24 - (length + (start % 8))); /* cut tail */
x = (x & (0xffff >> (16 - length))); /* cut head */ cl = s[start/8];
return(x); /* length */ cc = s[start/8 + 1];
cr = s[start/8 + 2];
x = (guint32) ((((cl << 8) | cc) << 8) | cr); /* 24 bits */
x = x >> (24 - (length + (start % 8))); /* cut tail */
x = (x & (0xffff >> (16 - length))); /* cut head */
return(x); /* length */
} }

View File

@ -1,9 +1,9 @@
/* /*
* Copyright (C) 2001 Nikos Mavroyanopoulos * Copyright (C) 2001 Nikos Mavroyanopoulos
* *
* This library is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 3 of the License, or * by the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
@ -17,7 +17,7 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
/* /*
* The algorithm is due to Ron Rivest. This code is based on code * The algorithm is due to Ron Rivest. This code is based on code
* written by Colin Plumb in 1993. * written by Colin Plumb in 1993.
*/ */
@ -42,12 +42,14 @@ static void byteReverse(unsigned char *buf, unsigned longs);
static void byteReverse(unsigned char *buf, unsigned longs) static void byteReverse(unsigned char *buf, unsigned longs)
{ {
guint32 t; guint32 t;
do { do
{
t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
((unsigned) buf[1] << 8 | buf[0]); ((unsigned) buf[1] << 8 | buf[0]);
*(guint32 *) buf = t; *(guint32 *) buf = t;
buf += 4; buf += 4;
} while (--longs); }
while (--longs);
} }
#endif #endif
@ -73,7 +75,7 @@ void MD4Init(MD4_CTX *ctx)
* of bytes. * of bytes.
*/ */
void MD4Update(MD4_CTX *ctx, unsigned char const *buf, void MD4Update(MD4_CTX *ctx, unsigned char const *buf,
unsigned len) unsigned len)
{ {
register guint32 t; register guint32 t;
@ -88,11 +90,13 @@ void MD4Update(MD4_CTX *ctx, unsigned char const *buf,
/* Handle any leading odd-sized chunks */ /* Handle any leading odd-sized chunks */
if (t) { if (t)
{
unsigned char *p = (unsigned char *) ctx->in + t; unsigned char *p = (unsigned char *) ctx->in + t;
t = 64 - t; t = 64 - t;
if (len < t) { if (len < t)
{
memcpy(p, buf, len); memcpy(p, buf, len);
return; return;
} }
@ -104,7 +108,8 @@ void MD4Update(MD4_CTX *ctx, unsigned char const *buf,
} }
/* Process data in 64-byte chunks */ /* Process data in 64-byte chunks */
while (len >= 64) { while (len >= 64)
{
memcpy(ctx->in, buf, 64); memcpy(ctx->in, buf, 64);
byteReverse(ctx->in, 16); byteReverse(ctx->in, 16);
MD4Transform(ctx->buf, (guint32 *) ctx->in); MD4Transform(ctx->buf, (guint32 *) ctx->in);
@ -118,7 +123,7 @@ void MD4Update(MD4_CTX *ctx, unsigned char const *buf,
} }
/* /*
* Final wrapup - pad to 64-byte boundary with the bit pattern * Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first) * 1 0* (64-bit count of bits processed, MSB-first)
*/ */
void MD4Final(unsigned char* digest, MD4_CTX *ctx) void MD4Final(unsigned char* digest, MD4_CTX *ctx)
@ -138,7 +143,8 @@ void MD4Final(unsigned char* digest, MD4_CTX *ctx)
count = 64 - 1 - count; count = 64 - 1 - count;
/* Pad out to 56 mod 64 */ /* Pad out to 56 mod 64 */
if (count < 8) { if (count < 8)
{
/* Two lots of padding: Pad the first block to 64 bytes */ /* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count); memset(p, 0, count);
byteReverse(ctx->in, 16); byteReverse(ctx->in, 16);
@ -146,7 +152,9 @@ void MD4Final(unsigned char* digest, MD4_CTX *ctx)
/* Now fill the next block with 56 bytes */ /* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56); memset(ctx->in, 0, 56);
} else { }
else
{
/* Pad block to 56 bytes */ /* Pad block to 56 bytes */
memset(p, 0, count - 8); memset(p, 0, count - 8);
} }
@ -158,7 +166,7 @@ void MD4Final(unsigned char* digest, MD4_CTX *ctx)
MD4Transform(ctx->buf, (guint32 *) ctx->in); MD4Transform(ctx->buf, (guint32 *) ctx->in);
byteReverse((unsigned char *) ctx->buf, 4); byteReverse((unsigned char *) ctx->buf, 4);
if (digest!=NULL) if (digest!=NULL)
memcpy(digest, ctx->buf, 16); memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
@ -317,10 +325,12 @@ int main(int argc, char *argv[])
md4 = (MD4_CTX *)malloc(sizeof(MD4_CTX)); md4 = (MD4_CTX *)malloc(sizeof(MD4_CTX));
MD4Init(md4); MD4Init(md4);
do { do
{
r = read(0, data, sizeof data); r = read(0, data, sizeof data);
MD4Update(md4, data, r); MD4Update(md4, data, r);
} while (r); }
while (r);
MD4Final(digest, md4); MD4Final(digest, md4);
printf("MD4 Digest is: "); printf("MD4 Digest is: ");

View File

@ -2,8 +2,9 @@
#define MD4_H #define MD4_H
#include <glib.h> #include <glib.h>
typedef struct { typedef struct
{
guint32 buf[4]; guint32 buf[4];
guint32 bits[2]; guint32 bits[2];
unsigned char in[64]; unsigned char in[64];

View File

@ -12,9 +12,9 @@ int MD5Keycrunch(char *result, const char *seed, const char *passhrase)
{ {
char *buf; char *buf;
gsize len; gsize len;
GChecksum *checksum; GChecksum *checksum;
guint8 digest[16]; guint8 digest[16];
gsize digest_len = sizeof (digest); gsize digest_len = sizeof (digest);
guint32 *results; guint32 *results;
len = strlen(seed) + strlen(passhrase); len = strlen(seed) + strlen(passhrase);
@ -27,41 +27,41 @@ int MD5Keycrunch(char *result, const char *seed, const char *passhrase)
strcat(buf, passhrase); strcat(buf, passhrase);
skey_sevenbit(buf); skey_sevenbit(buf);
checksum = g_checksum_new (G_CHECKSUM_MD5); checksum = g_checksum_new (G_CHECKSUM_MD5);
g_checksum_update (checksum, (const guchar *) buf, len); g_checksum_update (checksum, (const guchar *) buf, len);
g_free(buf); g_free(buf);
g_checksum_get_digest (checksum, digest, &digest_len); g_checksum_get_digest (checksum, digest, &digest_len);
g_assert (digest_len == 16); g_assert (digest_len == 16);
results = (guint32 *) digest; results = (guint32 *) digest;
results[0] ^= results[2]; results[0] ^= results[2];
results[1] ^= results[3]; results[1] ^= results[3];
memcpy((void *)result, (void *)results, SKEY_SIZE); memcpy((void *)result, (void *)results, SKEY_SIZE);
g_checksum_free (checksum); g_checksum_free (checksum);
return 0; return 0;
} }
void MD5SKey(char *x) void MD5SKey(char *x)
{ {
GChecksum *checksum; GChecksum *checksum;
guint8 digest[16]; guint8 digest[16];
gsize digest_len = sizeof (digest); gsize digest_len = sizeof (digest);
guint32 *results; guint32 *results;
checksum = g_checksum_new (G_CHECKSUM_MD5); checksum = g_checksum_new (G_CHECKSUM_MD5);
g_checksum_update (checksum, (const guchar *) x, SKEY_SIZE); g_checksum_update (checksum, (const guchar *) x, SKEY_SIZE);
g_checksum_get_digest (checksum, digest, &digest_len); g_checksum_get_digest (checksum, digest, &digest_len);
g_assert (digest_len == 16); g_assert (digest_len == 16);
results = (guint32 *) digest; results = (guint32 *) digest;
results[0] ^= results[2]; results[0] ^= results[2];
results[1] ^= results[3]; results[1] ^= results[3];
memcpy((void *)x, (void *)results, SKEY_SIZE); memcpy((void *)x, (void *)results, SKEY_SIZE);
g_checksum_free (checksum); g_checksum_free (checksum);
} }

View File

@ -27,13 +27,15 @@
*/ */
static void byteReverse(unsigned char *buf, unsigned longs) static void byteReverse(unsigned char *buf, unsigned longs)
{ {
guint32 t; guint32 t;
do { do
t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | {
((unsigned) buf[1] << 8 | buf[0]); t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
*(guint32 *) buf = t; ((unsigned) buf[1] << 8 | buf[0]);
buf += 4; *(guint32 *) buf = t;
} while (--longs); buf += 4;
}
while (--longs);
} }
#endif #endif
@ -41,10 +43,10 @@ static void byteReverse(unsigned char *buf, unsigned longs)
int SHA1Keycrunch(char *result, const char *seed, const char *passphrase) int SHA1Keycrunch(char *result, const char *seed, const char *passphrase)
{ {
char *buf; char *buf;
gsize len; gsize len;
GChecksum *checksum; GChecksum *checksum;
guint8 digest[20]; guint8 digest[20];
gsize digest_len = sizeof (digest); gsize digest_len = sizeof (digest);
guint32 *results; guint32 *results;
len = strlen(seed) + strlen(passphrase); len = strlen(seed) + strlen(passphrase);
@ -56,14 +58,14 @@ int SHA1Keycrunch(char *result, const char *seed, const char *passphrase)
strcat(buf, passphrase); strcat(buf, passphrase);
skey_sevenbit(buf); skey_sevenbit(buf);
checksum = g_checksum_new (G_CHECKSUM_SHA1); checksum = g_checksum_new (G_CHECKSUM_SHA1);
g_checksum_update (checksum, (const guchar *) buf, len); g_checksum_update (checksum, (const guchar *) buf, len);
g_free(buf); g_free(buf);
g_checksum_get_digest (checksum, digest, &digest_len); g_checksum_get_digest (checksum, digest, &digest_len);
g_assert (digest_len == 20); g_assert (digest_len == 20);
results = (guint32 *) digest; results = (guint32 *) digest;
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
HTONDIGEST(results); HTONDIGEST(results);
@ -71,31 +73,31 @@ int SHA1Keycrunch(char *result, const char *seed, const char *passphrase)
byteReverse((unsigned char *)digest, 5); byteReverse((unsigned char *)digest, 5);
#endif #endif
results = (guint32 *) digest; results = (guint32 *) digest;
results[0] ^= results[2]; results[0] ^= results[2];
results[1] ^= results[3]; results[1] ^= results[3];
results[0] ^= results[4]; results[0] ^= results[4];
memcpy((void *)result, (void *)results, SKEY_SIZE); memcpy((void *)result, (void *)results, SKEY_SIZE);
g_checksum_free (checksum); g_checksum_free (checksum);
return 0; return 0;
} }
void SHA1SKey(char *x) void SHA1SKey(char *x)
{ {
GChecksum *checksum; GChecksum *checksum;
guint8 digest[20]; guint8 digest[20];
gsize digest_len = sizeof (digest); gsize digest_len = sizeof (digest);
guint32 *results; guint32 *results;
checksum = g_checksum_new (G_CHECKSUM_SHA1); checksum = g_checksum_new (G_CHECKSUM_SHA1);
g_checksum_update (checksum, (const guchar *) x, SKEY_SIZE); g_checksum_update (checksum, (const guchar *) x, SKEY_SIZE);
g_checksum_get_digest (checksum, digest, &digest_len); g_checksum_get_digest (checksum, digest, &digest_len);
g_assert (digest_len == 20); g_assert (digest_len == 20);
results = (guint32 *) digest; results = (guint32 *) digest;
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
HTONDIGEST(results); HTONDIGEST(results);
#else #else
@ -108,5 +110,5 @@ void SHA1SKey(char *x)
memcpy((void *)x, (void *)results, SKEY_SIZE); memcpy((void *)x, (void *)results, SKEY_SIZE);
g_checksum_free (checksum); g_checksum_free (checksum);
} }

View File

@ -2,7 +2,7 @@
#define _SHA1_H #define _SHA1_H
#include <glib.h> #include <glib.h>
int SHA1Keycrunch(char *result, const char *seed, const char *passphrase); int SHA1Keycrunch(char *result, const char *seed, const char *passphrase);
void SHA1SKey(char *x); void SHA1SKey(char *x);

View File

@ -11,11 +11,13 @@
#include "skey.h" #include "skey.h"
#include "btoe.h" #include "btoe.h"
struct skey_hash { struct skey_hash
{
int (*Keycrunch) (char *, const char *, const char *); int (*Keycrunch) (char *, const char *, const char *);
void (*Skey) (char *); void (*Skey) (char *);
}; };
static struct skey_hash hash_table[] = { static struct skey_hash hash_table[] =
{
{ MD4Keycrunch, MD4SKey }, { MD4Keycrunch, MD4SKey },
{ MD5Keycrunch, MD5SKey }, { MD5Keycrunch, MD5SKey },
{ SHA1Keycrunch, SHA1SKey } { SHA1Keycrunch, SHA1SKey }
@ -26,7 +28,7 @@ char *skey(SKeyAlgorithm algorithm, int seq, const char *seed, const char *passp
{ {
char key[SKEY_SIZE]; char key[SKEY_SIZE];
int i; int i;
g_assert (algorithm < G_N_ELEMENTS (hash_table)); g_assert (algorithm < G_N_ELEMENTS (hash_table));
if (hash_table[algorithm].Keycrunch(key, seed, passphrase) == -1) if (hash_table[algorithm].Keycrunch(key, seed, passphrase) == -1)
return NULL; return NULL;

View File

@ -1,7 +1,8 @@
typedef enum { typedef enum
MD4, {
MD5, MD4,
SHA1 MD5,
SHA1
} SKeyAlgorithm; } SKeyAlgorithm;
#define SKEY_SIZE 8 #define SKEY_SIZE 8

View File

@ -8,8 +8,9 @@
#include "skey.h" #include "skey.h"
typedef struct { typedef struct
SKeyAlgorithm algorithm; {
SKeyAlgorithm algorithm;
const char *passphrase; const char *passphrase;
const char *seed; const char *seed;
int count; int count;
@ -17,7 +18,8 @@ typedef struct {
const char *btoe; const char *btoe;
} TestEntry; } TestEntry;
static const TestEntry tests[] = { static const TestEntry tests[] =
{
{ MD4, "This is a test.", "TeSt", 0, "D185 4218 EBBB 0B51", "ROME MUG FRED SCAN LIVE LACE" }, { MD4, "This is a test.", "TeSt", 0, "D185 4218 EBBB 0B51", "ROME MUG FRED SCAN LIVE LACE" },
{ MD4, "This is a test.", "TeSt", 1, "6347 3EF0 1CD0 B444", "CARD SAD MINI RYE COL KIN" }, { MD4, "This is a test.", "TeSt", 1, "6347 3EF0 1CD0 B444", "CARD SAD MINI RYE COL KIN" },
{ MD4, "This is a test.", "TeSt", 99, "C5E6 1277 6E6C 237A", "NOTE OUT IBIS SINK NAVE MODE" }, { MD4, "This is a test.", "TeSt", 99, "C5E6 1277 6E6C 237A", "NOTE OUT IBIS SINK NAVE MODE" },
@ -46,54 +48,56 @@ static const TestEntry tests[] = {
{ SHA1, "OTP's are good", "correct", 1, "82AE B52D 9437 74E4", "FLIT DOSE ALSO MEW DRUM DEFY" }, { SHA1, "OTP's are good", "correct", 1, "82AE B52D 9437 74E4", "FLIT DOSE ALSO MEW DRUM DEFY" },
{ SHA1, "OTP's are good", "correct", 99, "4F29 6A74 FE15 67EC", "AURA ALOE HURL WING BERG WAIT" }, { SHA1, "OTP's are good", "correct", 99, "4F29 6A74 FE15 67EC", "AURA ALOE HURL WING BERG WAIT" },
{ SHA1, "Passphrase", "IiIi", 100, "27F4 01CC 0AC8 5112", "MEG JACK DIET GAD FORK GARY" } { SHA1, "Passphrase", "IiIi", 100, "27F4 01CC 0AC8 5112", "MEG JACK DIET GAD FORK GARY" }
}; };
static const char *algos[] = { static const char *algos[] =
"MD4", {
"MD5", "MD4",
"SHA1" "MD5",
"SHA1"
}; };
static void static void
skey_test (gconstpointer data) skey_test (gconstpointer data)
{ {
const TestEntry *test = (const TestEntry *) data; const TestEntry *test = (const TestEntry *) data;
char *key; char *key;
key = skey (test->algorithm, key = skey (test->algorithm,
test->count, test->count,
test->seed, test->seed,
test->passphrase); test->passphrase);
g_assert (key != NULL); g_assert (key != NULL);
g_assert (strcmp (key, test->btoe) == 0); g_assert (strcmp (key, test->btoe) == 0);
free (key); free (key);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
guint i; guint i;
if (!setlocale (LC_ALL, "")) if (!setlocale (LC_ALL, ""))
g_error ("Locale not supported by C library!\n"); g_error ("Locale not supported by C library!\n");
g_test_init (&argc, &argv, NULL); g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.mate.org/enter_bug.cgi?product=mate-terminal"); g_test_bug_base ("http://bugzilla.mate.org/enter_bug.cgi?product=mate-terminal");
for (i = 0; i < G_N_ELEMENTS (tests); ++i) { for (i = 0; i < G_N_ELEMENTS (tests); ++i)
const TestEntry *test = &tests[i]; {
char *name; const TestEntry *test = &tests[i];
char *name;
name = g_strdup_printf ("/%s/%s/%s/%d/%s/%s", name = g_strdup_printf ("/%s/%s/%s/%d/%s/%s",
algos[test->algorithm], algos[test->algorithm],
test->passphrase, test->passphrase,
test->seed, test->seed,
test->count, test->count,
test->hex, test->hex,
test->btoe); test->btoe);
g_test_add_data_func (name, test, skey_test); g_test_add_data_func (name, test, skey_test);
g_free (name); g_free (name);
} }
return g_test_run (); return g_test_run ();
} }

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
void terminal_accels_init (void); void terminal_accels_init (void);
void terminal_accels_shutdown (void); void terminal_accels_shutdown (void);
void terminal_edit_keys_dialog_show (GtkWindow *transient_parent); void terminal_edit_keys_dialog_show (GtkWindow *transient_parent);

File diff suppressed because it is too large Load Diff

View File

@ -102,16 +102,16 @@ void terminal_app_new_profile (TerminalApp *app,
GtkWindow *transient_parent); GtkWindow *transient_parent);
TerminalWindow * terminal_app_new_window (TerminalApp *app, TerminalWindow * terminal_app_new_window (TerminalApp *app,
GdkScreen *screen); GdkScreen *screen);
TerminalScreen *terminal_app_new_terminal (TerminalApp *app, TerminalScreen *terminal_app_new_terminal (TerminalApp *app,
TerminalWindow *window, TerminalWindow *window,
TerminalProfile *profile, TerminalProfile *profile,
char **override_command, char **override_command,
const char *title, const char *title,
const char *working_dir, const char *working_dir,
char **child_env, char **child_env,
double zoom); double zoom);
TerminalWindow *terminal_app_get_current_window (TerminalApp *app); TerminalWindow *terminal_app_get_current_window (TerminalApp *app);
@ -129,10 +129,10 @@ GList* terminal_app_get_profile_list (TerminalApp *app);
TerminalProfile* terminal_app_ensure_profile_fallback (TerminalApp *app); TerminalProfile* terminal_app_ensure_profile_fallback (TerminalApp *app);
TerminalProfile* terminal_app_get_profile_by_name (TerminalApp *app, TerminalProfile* terminal_app_get_profile_by_name (TerminalApp *app,
const char *name); const char *name);
TerminalProfile* terminal_app_get_profile_by_visible_name (TerminalApp *app, TerminalProfile* terminal_app_get_profile_by_visible_name (TerminalApp *app,
const char *name); const char *name);
/* may return NULL */ /* may return NULL */
TerminalProfile* terminal_app_get_default_profile (TerminalApp *app); TerminalProfile* terminal_app_get_default_profile (TerminalApp *app);
@ -141,7 +141,7 @@ TerminalProfile* terminal_app_get_default_profile (TerminalApp *app);
TerminalProfile* terminal_app_get_profile_for_new_term (TerminalApp *app); TerminalProfile* terminal_app_get_profile_for_new_term (TerminalApp *app);
TerminalEncoding *terminal_app_ensure_encoding (TerminalApp *app, TerminalEncoding *terminal_app_ensure_encoding (TerminalApp *app,
const char *charset); const char *charset);
GHashTable *terminal_app_get_encodings (TerminalApp *app); GHashTable *terminal_app_get_encodings (TerminalApp *app);

View File

@ -28,18 +28,19 @@ void
_terminal_debug_init(void) _terminal_debug_init(void)
{ {
#ifdef MATE_ENABLE_DEBUG #ifdef MATE_ENABLE_DEBUG
const GDebugKey keys[] = { const GDebugKey keys[] =
{ "accels", TERMINAL_DEBUG_ACCELS }, {
{ "encodings", TERMINAL_DEBUG_ENCODINGS }, { "accels", TERMINAL_DEBUG_ACCELS },
{ "factory", TERMINAL_DEBUG_FACTORY }, { "encodings", TERMINAL_DEBUG_ENCODINGS },
{ "geometry", TERMINAL_DEBUG_GEOMETRY }, { "factory", TERMINAL_DEBUG_FACTORY },
{ "mdi", TERMINAL_DEBUG_MDI }, { "geometry", TERMINAL_DEBUG_GEOMETRY },
{ "processes", TERMINAL_DEBUG_PROCESSES }, { "mdi", TERMINAL_DEBUG_MDI },
{ "profile", TERMINAL_DEBUG_PROFILE } { "processes", TERMINAL_DEBUG_PROCESSES },
}; { "profile", TERMINAL_DEBUG_PROFILE }
};
_terminal_debug_flags = g_parse_debug_string (g_getenv ("MATE_TERMINAL_DEBUG"), _terminal_debug_flags = g_parse_debug_string (g_getenv ("MATE_TERMINAL_DEBUG"),
keys, G_N_ELEMENTS (keys)); keys, G_N_ELEMENTS (keys));
#endif /* MATE_ENABLE_DEBUG */ #endif /* MATE_ENABLE_DEBUG */
} }

View File

@ -25,14 +25,15 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum { typedef enum
TERMINAL_DEBUG_ACCELS = 1 << 0, {
TERMINAL_DEBUG_ENCODINGS = 1 << 1, TERMINAL_DEBUG_ACCELS = 1 << 0,
TERMINAL_DEBUG_FACTORY = 1 << 2, TERMINAL_DEBUG_ENCODINGS = 1 << 1,
TERMINAL_DEBUG_GEOMETRY = 1 << 3, TERMINAL_DEBUG_FACTORY = 1 << 2,
TERMINAL_DEBUG_MDI = 1 << 4, TERMINAL_DEBUG_GEOMETRY = 1 << 3,
TERMINAL_DEBUG_PROCESSES = 1 << 5, TERMINAL_DEBUG_MDI = 1 << 4,
TERMINAL_DEBUG_PROFILE = 1 << 6 TERMINAL_DEBUG_PROCESSES = 1 << 5,
TERMINAL_DEBUG_PROFILE = 1 << 6
} TerminalDebugFlags; } TerminalDebugFlags;
void _terminal_debug_init(void); void _terminal_debug_init(void);
@ -43,7 +44,7 @@ static inline gboolean _terminal_debug_on (TerminalDebugFlags flags) G_GNUC_CONS
static inline gboolean static inline gboolean
_terminal_debug_on (TerminalDebugFlags flags) _terminal_debug_on (TerminalDebugFlags flags)
{ {
return (_terminal_debug_flags & flags) == flags; return (_terminal_debug_flags & flags) == flags;
} }
#ifdef MATE_ENABLE_DEBUG #ifdef MATE_ENABLE_DEBUG
@ -60,12 +61,13 @@ _terminal_debug_on (TerminalDebugFlags flags)
#include <glib/gstdio.h> #include <glib/gstdio.h>
static void _terminal_debug_print (guint flags, const char *fmt, ...) static void _terminal_debug_print (guint flags, const char *fmt, ...)
{ {
if (_terminal_debug_on (flags)) { if (_terminal_debug_on (flags))
va_list ap; {
va_start (ap, fmt); va_list ap;
g_vfprintf (stderr, fmt, ap); va_start (ap, fmt);
va_end (ap); g_vfprintf (stderr, fmt, ap);
} va_end (ap);
}
} }
#endif #endif

View File

@ -33,7 +33,7 @@
* *
* There's a list of character sets stored in mateconf, indicating * There's a list of character sets stored in mateconf, indicating
* which encodings to display in the encoding menu. * which encodings to display in the encoding menu.
* *
* We have a pre-canned list of available encodings * We have a pre-canned list of available encodings
* (hardcoded in the table below) that can be added to * (hardcoded in the table below) that can be added to
* the encoding menu, and to give a human-readable name * the encoding menu, and to give a human-readable name
@ -44,101 +44,104 @@
* labeled "user defined" but still appears in the menu. * labeled "user defined" but still appears in the menu.
*/ */
static const struct { static const struct
const char *charset; {
const char *name; const char *charset;
} encodings[] = { const char *name;
{ "ISO-8859-1", N_("Western") }, } encodings[] =
{ "ISO-8859-2", N_("Central European") }, {
{ "ISO-8859-3", N_("South European") }, { "ISO-8859-1", N_("Western") },
{ "ISO-8859-4", N_("Baltic") }, { "ISO-8859-2", N_("Central European") },
{ "ISO-8859-5", N_("Cyrillic") }, { "ISO-8859-3", N_("South European") },
{ "ISO-8859-6", N_("Arabic") }, { "ISO-8859-4", N_("Baltic") },
{ "ISO-8859-7", N_("Greek") }, { "ISO-8859-5", N_("Cyrillic") },
{ "ISO-8859-8", N_("Hebrew Visual") }, { "ISO-8859-6", N_("Arabic") },
{ "ISO-8859-8-I", N_("Hebrew") }, { "ISO-8859-7", N_("Greek") },
{ "ISO-8859-9", N_("Turkish") }, { "ISO-8859-8", N_("Hebrew Visual") },
{ "ISO-8859-10", N_("Nordic") }, { "ISO-8859-8-I", N_("Hebrew") },
{ "ISO-8859-13", N_("Baltic") }, { "ISO-8859-9", N_("Turkish") },
{ "ISO-8859-14", N_("Celtic") }, { "ISO-8859-10", N_("Nordic") },
{ "ISO-8859-15", N_("Western") }, { "ISO-8859-13", N_("Baltic") },
{ "ISO-8859-16", N_("Romanian") }, { "ISO-8859-14", N_("Celtic") },
{ "UTF-8", N_("Unicode") }, { "ISO-8859-15", N_("Western") },
{ "ARMSCII-8", N_("Armenian") }, { "ISO-8859-16", N_("Romanian") },
{ "BIG5", N_("Chinese Traditional") }, { "UTF-8", N_("Unicode") },
{ "BIG5-HKSCS", N_("Chinese Traditional") }, { "ARMSCII-8", N_("Armenian") },
{ "CP866", N_("Cyrillic/Russian") }, { "BIG5", N_("Chinese Traditional") },
{ "EUC-JP", N_("Japanese") }, { "BIG5-HKSCS", N_("Chinese Traditional") },
{ "EUC-KR", N_("Korean") }, { "CP866", N_("Cyrillic/Russian") },
{ "EUC-TW", N_("Chinese Traditional") }, { "EUC-JP", N_("Japanese") },
{ "GB18030", N_("Chinese Simplified") }, { "EUC-KR", N_("Korean") },
{ "GB2312", N_("Chinese Simplified") }, { "EUC-TW", N_("Chinese Traditional") },
{ "GBK", N_("Chinese Simplified") }, { "GB18030", N_("Chinese Simplified") },
{ "GEORGIAN-PS", N_("Georgian") }, { "GB2312", N_("Chinese Simplified") },
{ "IBM850", N_("Western") }, { "GBK", N_("Chinese Simplified") },
{ "IBM852", N_("Central European") }, { "GEORGIAN-PS", N_("Georgian") },
{ "IBM855", N_("Cyrillic") }, { "IBM850", N_("Western") },
{ "IBM857", N_("Turkish") }, { "IBM852", N_("Central European") },
{ "IBM862", N_("Hebrew") }, { "IBM855", N_("Cyrillic") },
{ "IBM864", N_("Arabic") }, { "IBM857", N_("Turkish") },
{ "ISO-2022-JP", N_("Japanese") }, { "IBM862", N_("Hebrew") },
{ "ISO-2022-KR", N_("Korean") }, { "IBM864", N_("Arabic") },
{ "ISO-IR-111", N_("Cyrillic") }, { "ISO-2022-JP", N_("Japanese") },
{ "KOI8-R", N_("Cyrillic") }, { "ISO-2022-KR", N_("Korean") },
{ "KOI8-U", N_("Cyrillic/Ukrainian") }, { "ISO-IR-111", N_("Cyrillic") },
{ "MAC_ARABIC", N_("Arabic") }, { "KOI8-R", N_("Cyrillic") },
{ "MAC_CE", N_("Central European") }, { "KOI8-U", N_("Cyrillic/Ukrainian") },
{ "MAC_CROATIAN", N_("Croatian") }, { "MAC_ARABIC", N_("Arabic") },
{ "MAC-CYRILLIC", N_("Cyrillic") }, { "MAC_CE", N_("Central European") },
{ "MAC_DEVANAGARI", N_("Hindi") }, { "MAC_CROATIAN", N_("Croatian") },
{ "MAC_FARSI", N_("Persian") }, { "MAC-CYRILLIC", N_("Cyrillic") },
{ "MAC_GREEK", N_("Greek") }, { "MAC_DEVANAGARI", N_("Hindi") },
{ "MAC_GUJARATI", N_("Gujarati") }, { "MAC_FARSI", N_("Persian") },
{ "MAC_GURMUKHI", N_("Gurmukhi") }, { "MAC_GREEK", N_("Greek") },
{ "MAC_HEBREW", N_("Hebrew") }, { "MAC_GUJARATI", N_("Gujarati") },
{ "MAC_ICELANDIC", N_("Icelandic") }, { "MAC_GURMUKHI", N_("Gurmukhi") },
{ "MAC_ROMAN", N_("Western") }, { "MAC_HEBREW", N_("Hebrew") },
{ "MAC_ROMANIAN", N_("Romanian") }, { "MAC_ICELANDIC", N_("Icelandic") },
{ "MAC_TURKISH", N_("Turkish") }, { "MAC_ROMAN", N_("Western") },
{ "MAC_UKRAINIAN", N_("Cyrillic/Ukrainian") }, { "MAC_ROMANIAN", N_("Romanian") },
{ "SHIFT_JIS", N_("Japanese") }, { "MAC_TURKISH", N_("Turkish") },
{ "TCVN", N_("Vietnamese") }, { "MAC_UKRAINIAN", N_("Cyrillic/Ukrainian") },
{ "TIS-620", N_("Thai") }, { "SHIFT_JIS", N_("Japanese") },
{ "UHC", N_("Korean") }, { "TCVN", N_("Vietnamese") },
{ "VISCII", N_("Vietnamese") }, { "TIS-620", N_("Thai") },
{ "WINDOWS-1250", N_("Central European") }, { "UHC", N_("Korean") },
{ "WINDOWS-1251", N_("Cyrillic") }, { "VISCII", N_("Vietnamese") },
{ "WINDOWS-1252", N_("Western") }, { "WINDOWS-1250", N_("Central European") },
{ "WINDOWS-1253", N_("Greek") }, { "WINDOWS-1251", N_("Cyrillic") },
{ "WINDOWS-1254", N_("Turkish") }, { "WINDOWS-1252", N_("Western") },
{ "WINDOWS-1255", N_("Hebrew") }, { "WINDOWS-1253", N_("Greek") },
{ "WINDOWS-1256", N_("Arabic") }, { "WINDOWS-1254", N_("Turkish") },
{ "WINDOWS-1257", N_("Baltic") }, { "WINDOWS-1255", N_("Hebrew") },
{ "WINDOWS-1258", N_("Vietnamese") }, { "WINDOWS-1256", N_("Arabic") },
{ "WINDOWS-1257", N_("Baltic") },
{ "WINDOWS-1258", N_("Vietnamese") },
#if 0 #if 0
/* These encodings do NOT pass-through ASCII, so are always rejected. /* These encodings do NOT pass-through ASCII, so are always rejected.
* FIXME: why are they in this table; or rather why do we need * FIXME: why are they in this table; or rather why do we need
* the ASCII pass-through requirement? * the ASCII pass-through requirement?
*/ */
{ "UTF-7", N_("Unicode") }, { "UTF-7", N_("Unicode") },
{ "UTF-16", N_("Unicode") }, { "UTF-16", N_("Unicode") },
{ "UCS-2", N_("Unicode") }, { "UCS-2", N_("Unicode") },
{ "UCS-4", N_("Unicode") }, { "UCS-4", N_("Unicode") },
{ "JOHAB", N_("Korean") }, { "JOHAB", N_("Korean") },
#endif #endif
}; };
typedef struct { typedef struct
GtkWidget *dialog; {
GtkListStore *base_store; GtkWidget *dialog;
GtkTreeView *available_tree_view; GtkListStore *base_store;
GtkTreeSelection *available_selection; GtkTreeView *available_tree_view;
GtkTreeModel *available_model; GtkTreeSelection *available_selection;
GtkTreeView *active_tree_view; GtkTreeModel *available_model;
GtkTreeSelection *active_selection; GtkTreeView *active_tree_view;
GtkTreeModel *active_model; GtkTreeSelection *active_selection;
GtkWidget *add_button; GtkTreeModel *active_model;
GtkWidget *remove_button; GtkWidget *add_button;
GtkWidget *remove_button;
} EncodingDialogData; } EncodingDialogData;
static GtkWidget *encoding_dialog = NULL; static GtkWidget *encoding_dialog = NULL;
@ -149,163 +152,164 @@ terminal_encoding_new (const char *charset,
gboolean is_custom, gboolean is_custom,
gboolean force_valid) gboolean force_valid)
{ {
TerminalEncoding *encoding; TerminalEncoding *encoding;
encoding = g_slice_new (TerminalEncoding); encoding = g_slice_new (TerminalEncoding);
encoding->refcount = 1; encoding->refcount = 1;
encoding->id = g_strdup (charset); encoding->id = g_strdup (charset);
encoding->name = g_strdup (display_name); encoding->name = g_strdup (display_name);
encoding->valid = encoding->validity_checked = force_valid; encoding->valid = encoding->validity_checked = force_valid;
encoding->is_custom = is_custom; encoding->is_custom = is_custom;
encoding->is_active = FALSE; encoding->is_active = FALSE;
return encoding; return encoding;
} }
TerminalEncoding* TerminalEncoding*
terminal_encoding_ref (TerminalEncoding *encoding) terminal_encoding_ref (TerminalEncoding *encoding)
{ {
g_return_val_if_fail (encoding != NULL, NULL); g_return_val_if_fail (encoding != NULL, NULL);
encoding->refcount++; encoding->refcount++;
return encoding; return encoding;
} }
void void
terminal_encoding_unref (TerminalEncoding *encoding) terminal_encoding_unref (TerminalEncoding *encoding)
{ {
if (--encoding->refcount > 0) if (--encoding->refcount > 0)
return; return;
g_free (encoding->name); g_free (encoding->name);
g_free (encoding->id); g_free (encoding->id);
g_slice_free (TerminalEncoding, encoding); g_slice_free (TerminalEncoding, encoding);
} }
const char * const char *
terminal_encoding_get_id (TerminalEncoding *encoding) terminal_encoding_get_id (TerminalEncoding *encoding)
{ {
g_return_val_if_fail (encoding != NULL, NULL); g_return_val_if_fail (encoding != NULL, NULL);
return encoding->id; return encoding->id;
} }
const char * const char *
terminal_encoding_get_charset (TerminalEncoding *encoding) terminal_encoding_get_charset (TerminalEncoding *encoding)
{ {
g_return_val_if_fail (encoding != NULL, NULL); g_return_val_if_fail (encoding != NULL, NULL);
if (strcmp (encoding->id, "current") == 0) if (strcmp (encoding->id, "current") == 0)
{ {
const char *charset; const char *charset;
g_get_charset (&charset); g_get_charset (&charset);
return charset; return charset;
} }
return encoding->id; return encoding->id;
} }
gboolean gboolean
terminal_encoding_is_valid (TerminalEncoding *encoding) terminal_encoding_is_valid (TerminalEncoding *encoding)
{ {
/* All of the printing ASCII characters from space (32) to the tilde (126) */ /* All of the printing ASCII characters from space (32) to the tilde (126) */
static const char ascii_sample[] = static const char ascii_sample[] =
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
char *converted; char *converted;
gsize bytes_read = 0, bytes_written = 0; gsize bytes_read = 0, bytes_written = 0;
GError *error = NULL; GError *error = NULL;
if (encoding->validity_checked) if (encoding->validity_checked)
return encoding->valid; return encoding->valid;
/* Test that the encoding is a proper superset of ASCII (which naive /* Test that the encoding is a proper superset of ASCII (which naive
* apps are going to use anyway) by attempting to validate the text * apps are going to use anyway) by attempting to validate the text
* using the current encoding. This also flushes out any encodings * using the current encoding. This also flushes out any encodings
* which the underlying GIConv implementation can't support. * which the underlying GIConv implementation can't support.
*/ */
converted = g_convert (ascii_sample, sizeof (ascii_sample) - 1, converted = g_convert (ascii_sample, sizeof (ascii_sample) - 1,
terminal_encoding_get_charset (encoding), "UTF-8", terminal_encoding_get_charset (encoding), "UTF-8",
&bytes_read, &bytes_written, &error); &bytes_read, &bytes_written, &error);
/* The encoding is only valid if ASCII passes through cleanly. */ /* The encoding is only valid if ASCII passes through cleanly. */
encoding->valid = (bytes_read == (sizeof (ascii_sample) - 1)) && encoding->valid = (bytes_read == (sizeof (ascii_sample) - 1)) &&
(converted != NULL) && (converted != NULL) &&
(strcmp (converted, ascii_sample) == 0); (strcmp (converted, ascii_sample) == 0);
#ifdef MATE_ENABLE_DEBUG #ifdef MATE_ENABLE_DEBUG
_TERMINAL_DEBUG_IF (TERMINAL_DEBUG_ENCODINGS) _TERMINAL_DEBUG_IF (TERMINAL_DEBUG_ENCODINGS)
{ {
if (!encoding->valid) if (!encoding->valid)
{ {
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS, _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
"Rejecting encoding %s as invalid:\n", "Rejecting encoding %s as invalid:\n",
terminal_encoding_get_charset (encoding)); terminal_encoding_get_charset (encoding));
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS, _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
" input \"%s\"\n", " input \"%s\"\n",
ascii_sample); ascii_sample);
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS, _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
" output \"%s\" bytes read %u written %u\n", " output \"%s\" bytes read %u written %u\n",
converted ? converted : "(null)", bytes_read, bytes_written); converted ? converted : "(null)", bytes_read, bytes_written);
if (error) if (error)
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS, _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
" Error: %s\n", " Error: %s\n",
error->message); error->message);
} }
else else
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS, _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
"Encoding %s is valid\n\n", "Encoding %s is valid\n\n",
terminal_encoding_get_charset (encoding)); terminal_encoding_get_charset (encoding));
} }
#endif #endif
g_clear_error (&error); g_clear_error (&error);
g_free (converted); g_free (converted);
encoding->validity_checked = TRUE; encoding->validity_checked = TRUE;
return encoding->valid; return encoding->valid;
} }
GType GType
terminal_encoding_get_type (void) terminal_encoding_get_type (void)
{ {
static GType type = 0; static GType type = 0;
if (G_UNLIKELY (type == 0)) { if (G_UNLIKELY (type == 0))
type = g_boxed_type_register_static (I_("TerminalEncoding"), {
(GBoxedCopyFunc) terminal_encoding_ref, type = g_boxed_type_register_static (I_("TerminalEncoding"),
(GBoxedFreeFunc) terminal_encoding_unref); (GBoxedCopyFunc) terminal_encoding_ref,
} (GBoxedFreeFunc) terminal_encoding_unref);
}
return type; return type;
} }
static void static void
update_active_encodings_mateconf (void) update_active_encodings_mateconf (void)
{ {
GSList *list, *l; GSList *list, *l;
GSList *strings = NULL; GSList *strings = NULL;
MateConfClient *conf; MateConfClient *conf;
list = terminal_app_get_active_encodings (terminal_app_get ()); list = terminal_app_get_active_encodings (terminal_app_get ());
for (l = list; l != NULL; l = l->next) for (l = list; l != NULL; l = l->next)
{ {
TerminalEncoding *encoding = (TerminalEncoding *) l->data; TerminalEncoding *encoding = (TerminalEncoding *) l->data;
strings = g_slist_prepend (strings, (gpointer) terminal_encoding_get_id (encoding)); strings = g_slist_prepend (strings, (gpointer) terminal_encoding_get_id (encoding));
} }
conf = mateconf_client_get_default (); conf = mateconf_client_get_default ();
mateconf_client_set_list (conf, mateconf_client_set_list (conf,
CONF_GLOBAL_PREFIX"/active_encodings", CONF_GLOBAL_PREFIX"/active_encodings",
MATECONF_VALUE_STRING, MATECONF_VALUE_STRING,
strings, strings,
NULL); NULL);
g_object_unref (conf); g_object_unref (conf);
g_slist_free (strings); g_slist_free (strings);
g_slist_foreach (list, (GFunc) terminal_encoding_unref, NULL); g_slist_foreach (list, (GFunc) terminal_encoding_unref, NULL);
g_slist_free (list); g_slist_free (list);
} }
static void static void
@ -313,78 +317,78 @@ response_callback (GtkWidget *window,
int id, int id,
EncodingDialogData *data) EncodingDialogData *data)
{ {
if (id == GTK_RESPONSE_HELP) if (id == GTK_RESPONSE_HELP)
terminal_util_show_help ("mate-terminal-encoding-add", GTK_WINDOW (window)); terminal_util_show_help ("mate-terminal-encoding-add", GTK_WINDOW (window));
else else
gtk_widget_destroy (GTK_WIDGET (window)); gtk_widget_destroy (GTK_WIDGET (window));
} }
enum enum
{ {
COLUMN_NAME, COLUMN_NAME,
COLUMN_CHARSET, COLUMN_CHARSET,
COLUMN_DATA, COLUMN_DATA,
N_COLUMNS N_COLUMNS
}; };
static void static void
selection_changed_cb (GtkTreeSelection *selection, selection_changed_cb (GtkTreeSelection *selection,
EncodingDialogData *data) EncodingDialogData *data)
{ {
GtkWidget *button; GtkWidget *button;
gboolean have_selection; gboolean have_selection;
if (selection == data->available_selection) if (selection == data->available_selection)
button = data->add_button; button = data->add_button;
else if (selection == data->active_selection) else if (selection == data->active_selection)
button = data->remove_button; button = data->remove_button;
else else
g_assert_not_reached (); g_assert_not_reached ();
have_selection = gtk_tree_selection_get_selected (selection, NULL, NULL); have_selection = gtk_tree_selection_get_selected (selection, NULL, NULL);
gtk_widget_set_sensitive (button, have_selection); gtk_widget_set_sensitive (button, have_selection);
} }
static void static void
button_clicked_cb (GtkWidget *button, button_clicked_cb (GtkWidget *button,
EncodingDialogData *data) EncodingDialogData *data)
{ {
GtkTreeSelection *selection; GtkTreeSelection *selection;
GtkTreeModel *model; GtkTreeModel *model;
GtkTreeIter filter_iter, iter; GtkTreeIter filter_iter, iter;
TerminalEncoding *encoding; TerminalEncoding *encoding;
if (button == data->add_button) if (button == data->add_button)
selection = data->available_selection; selection = data->available_selection;
else if (button == data->remove_button) else if (button == data->remove_button)
selection = data->active_selection; selection = data->active_selection;
else else
g_assert_not_reached (); g_assert_not_reached ();
if (!gtk_tree_selection_get_selected (selection, &model, &filter_iter)) if (!gtk_tree_selection_get_selected (selection, &model, &filter_iter))
return; return;
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
&iter, &iter,
&filter_iter); &filter_iter);
model = GTK_TREE_MODEL (data->base_store); model = GTK_TREE_MODEL (data->base_store);
gtk_tree_model_get (model, &iter, COLUMN_DATA, &encoding, -1); gtk_tree_model_get (model, &iter, COLUMN_DATA, &encoding, -1);
g_assert (encoding != NULL); g_assert (encoding != NULL);
if (button == data->add_button) if (button == data->add_button)
encoding->is_active = TRUE; encoding->is_active = TRUE;
else if (button == data->remove_button) else if (button == data->remove_button)
encoding->is_active = FALSE; encoding->is_active = FALSE;
else else
g_assert_not_reached (); g_assert_not_reached ();
terminal_encoding_unref (encoding); terminal_encoding_unref (encoding);
/* We don't need to emit row-changed here, since updating the mateconf pref /* We don't need to emit row-changed here, since updating the mateconf pref
* will update the models. * will update the models.
*/ */
update_active_encodings_mateconf (); update_active_encodings_mateconf ();
} }
static void static void
@ -392,16 +396,16 @@ liststore_insert_encoding (gpointer key,
TerminalEncoding *encoding, TerminalEncoding *encoding,
GtkListStore *store) GtkListStore *store)
{ {
GtkTreeIter iter; GtkTreeIter iter;
if (!terminal_encoding_is_valid (encoding)) if (!terminal_encoding_is_valid (encoding))
return; return;
gtk_list_store_insert_with_values (store, &iter, -1, gtk_list_store_insert_with_values (store, &iter, -1,
COLUMN_CHARSET, terminal_encoding_get_charset (encoding), COLUMN_CHARSET, terminal_encoding_get_charset (encoding),
COLUMN_NAME, encoding->name, COLUMN_NAME, encoding->name,
COLUMN_DATA, encoding, COLUMN_DATA, encoding,
-1); -1);
} }
static gboolean static gboolean
@ -409,206 +413,206 @@ filter_active_encodings (GtkTreeModel *child_model,
GtkTreeIter *child_iter, GtkTreeIter *child_iter,
gpointer data) gpointer data)
{ {
TerminalEncoding *encoding; TerminalEncoding *encoding;
gboolean active = GPOINTER_TO_UINT (data); gboolean active = GPOINTER_TO_UINT (data);
gboolean visible; gboolean visible;
gtk_tree_model_get (child_model, child_iter, COLUMN_DATA, &encoding, -1); gtk_tree_model_get (child_model, child_iter, COLUMN_DATA, &encoding, -1);
visible = active ? encoding->is_active : !encoding->is_active; visible = active ? encoding->is_active : !encoding->is_active;
terminal_encoding_unref (encoding); terminal_encoding_unref (encoding);
return visible; return visible;
} }
static GtkTreeModel * static GtkTreeModel *
encodings_create_treemodel (GtkListStore *base_store, encodings_create_treemodel (GtkListStore *base_store,
gboolean active) gboolean active)
{ {
GtkTreeModel *model; GtkTreeModel *model;
model = gtk_tree_model_filter_new (GTK_TREE_MODEL (base_store), NULL); model = gtk_tree_model_filter_new (GTK_TREE_MODEL (base_store), NULL);
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model), gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model),
filter_active_encodings, filter_active_encodings,
GUINT_TO_POINTER (active), NULL); GUINT_TO_POINTER (active), NULL);
return model; return model;
} }
static void static void
encodings_list_changed_cb (TerminalApp *app, encodings_list_changed_cb (TerminalApp *app,
EncodingDialogData *data) EncodingDialogData *data)
{ {
gtk_list_store_clear (data->base_store); gtk_list_store_clear (data->base_store);
g_hash_table_foreach (terminal_app_get_encodings (app), (GHFunc) liststore_insert_encoding, data->base_store); g_hash_table_foreach (terminal_app_get_encodings (app), (GHFunc) liststore_insert_encoding, data->base_store);
} }
static void static void
encoding_dialog_data_free (EncodingDialogData *data) encoding_dialog_data_free (EncodingDialogData *data)
{ {
g_signal_handlers_disconnect_by_func (terminal_app_get (), g_signal_handlers_disconnect_by_func (terminal_app_get (),
G_CALLBACK (encodings_list_changed_cb), G_CALLBACK (encodings_list_changed_cb),
data); data);
g_free (data); g_free (data);
} }
void void
terminal_encoding_dialog_show (GtkWindow *transient_parent) terminal_encoding_dialog_show (GtkWindow *transient_parent)
{ {
TerminalApp *app; TerminalApp *app;
GtkCellRenderer *cell_renderer; GtkCellRenderer *cell_renderer;
GtkTreeViewColumn *column; GtkTreeViewColumn *column;
GtkTreeModel *model; GtkTreeModel *model;
EncodingDialogData *data; EncodingDialogData *data;
if (encoding_dialog) if (encoding_dialog)
{ {
gtk_window_set_transient_for (GTK_WINDOW (encoding_dialog), transient_parent); gtk_window_set_transient_for (GTK_WINDOW (encoding_dialog), transient_parent);
gtk_window_present (GTK_WINDOW (encoding_dialog)); gtk_window_present (GTK_WINDOW (encoding_dialog));
return; return;
} }
data = g_new (EncodingDialogData, 1); data = g_new (EncodingDialogData, 1);
if (!terminal_util_load_builder_file ("encodings-dialog.ui", if (!terminal_util_load_builder_file ("encodings-dialog.ui",
"encodings-dialog", &data->dialog, "encodings-dialog", &data->dialog,
"add-button", &data->add_button, "add-button", &data->add_button,
"remove-button", &data->remove_button, "remove-button", &data->remove_button,
"available-treeview", &data->available_tree_view, "available-treeview", &data->available_tree_view,
"displayed-treeview", &data->active_tree_view, "displayed-treeview", &data->active_tree_view,
NULL)) NULL))
{ {
g_free (data); g_free (data);
return; return;
} }
g_object_set_data_full (G_OBJECT (data->dialog), "GT::Data", data, (GDestroyNotify) encoding_dialog_data_free); g_object_set_data_full (G_OBJECT (data->dialog), "GT::Data", data, (GDestroyNotify) encoding_dialog_data_free);
gtk_window_set_transient_for (GTK_WINDOW (data->dialog), transient_parent); gtk_window_set_transient_for (GTK_WINDOW (data->dialog), transient_parent);
gtk_window_set_role (GTK_WINDOW (data->dialog), "mate-terminal-encodings"); gtk_window_set_role (GTK_WINDOW (data->dialog), "mate-terminal-encodings");
g_signal_connect (data->dialog, "response", g_signal_connect (data->dialog, "response",
G_CALLBACK (response_callback), data); G_CALLBACK (response_callback), data);
/* buttons */ /* buttons */
g_signal_connect (data->add_button, "clicked", g_signal_connect (data->add_button, "clicked",
G_CALLBACK (button_clicked_cb), data); G_CALLBACK (button_clicked_cb), data);
g_signal_connect (data->remove_button, "clicked", g_signal_connect (data->remove_button, "clicked",
G_CALLBACK (button_clicked_cb), data); G_CALLBACK (button_clicked_cb), data);
/* Tree view of available encodings */
/* Column 1 */
cell_renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("_Description"),
cell_renderer,
"text", COLUMN_NAME,
NULL);
gtk_tree_view_append_column (data->available_tree_view, column);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
/* Column 2 */
cell_renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
cell_renderer,
"text", COLUMN_CHARSET,
NULL);
gtk_tree_view_append_column (data->available_tree_view, column);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
data->available_selection = gtk_tree_view_get_selection (data->available_tree_view); /* Tree view of available encodings */
gtk_tree_selection_set_mode (data->available_selection, GTK_SELECTION_BROWSE); /* Column 1 */
cell_renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("_Description"),
cell_renderer,
"text", COLUMN_NAME,
NULL);
gtk_tree_view_append_column (data->available_tree_view, column);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
g_signal_connect (data->available_selection, "changed", /* Column 2 */
G_CALLBACK (selection_changed_cb), data); cell_renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
cell_renderer,
"text", COLUMN_CHARSET,
NULL);
gtk_tree_view_append_column (data->available_tree_view, column);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
/* Tree view of selected encodings */ data->available_selection = gtk_tree_view_get_selection (data->available_tree_view);
/* Column 1 */ gtk_tree_selection_set_mode (data->available_selection, GTK_SELECTION_BROWSE);
cell_renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("_Description"),
cell_renderer,
"text", COLUMN_NAME,
NULL);
gtk_tree_view_append_column (data->active_tree_view, column);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
/* Column 2 */
cell_renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
cell_renderer,
"text", COLUMN_CHARSET,
NULL);
gtk_tree_view_append_column (data->active_tree_view, column);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
/* Add the data */ g_signal_connect (data->available_selection, "changed",
G_CALLBACK (selection_changed_cb), data);
data->active_selection = gtk_tree_view_get_selection (data->active_tree_view); /* Tree view of selected encodings */
gtk_tree_selection_set_mode (data->active_selection, GTK_SELECTION_BROWSE); /* Column 1 */
cell_renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("_Description"),
cell_renderer,
"text", COLUMN_NAME,
NULL);
gtk_tree_view_append_column (data->active_tree_view, column);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
g_signal_connect (data->active_selection, "changed", /* Column 2 */
G_CALLBACK (selection_changed_cb), data); cell_renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
cell_renderer,
"text", COLUMN_CHARSET,
NULL);
gtk_tree_view_append_column (data->active_tree_view, column);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
data->base_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, TERMINAL_TYPE_ENCODING); /* Add the data */
app = terminal_app_get (); data->active_selection = gtk_tree_view_get_selection (data->active_tree_view);
encodings_list_changed_cb (app, data); gtk_tree_selection_set_mode (data->active_selection, GTK_SELECTION_BROWSE);
g_signal_connect (app, "encoding-list-changed",
G_CALLBACK (encodings_list_changed_cb), data);
/* Now turn on sorting */ g_signal_connect (data->active_selection, "changed",
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->base_store), G_CALLBACK (selection_changed_cb), data);
COLUMN_NAME,
GTK_SORT_ASCENDING);
model = encodings_create_treemodel (data->base_store, FALSE);
gtk_tree_view_set_model (data->available_tree_view, model);
g_object_unref (model);
model = encodings_create_treemodel (data->base_store, TRUE); data->base_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, TERMINAL_TYPE_ENCODING);
gtk_tree_view_set_model (data->active_tree_view, model);
g_object_unref (model);
g_object_unref (data->base_store); app = terminal_app_get ();
encodings_list_changed_cb (app, data);
g_signal_connect (app, "encoding-list-changed",
G_CALLBACK (encodings_list_changed_cb), data);
gtk_window_present (GTK_WINDOW (data->dialog)); /* Now turn on sorting */
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->base_store),
COLUMN_NAME,
GTK_SORT_ASCENDING);
encoding_dialog = data->dialog; model = encodings_create_treemodel (data->base_store, FALSE);
g_signal_connect (data->dialog, "destroy", gtk_tree_view_set_model (data->available_tree_view, model);
G_CALLBACK (gtk_widget_destroyed), &encoding_dialog); g_object_unref (model);
model = encodings_create_treemodel (data->base_store, TRUE);
gtk_tree_view_set_model (data->active_tree_view, model);
g_object_unref (model);
g_object_unref (data->base_store);
gtk_window_present (GTK_WINDOW (data->dialog));
encoding_dialog = data->dialog;
g_signal_connect (data->dialog, "destroy",
G_CALLBACK (gtk_widget_destroyed), &encoding_dialog);
} }
GHashTable * GHashTable *
terminal_encodings_get_builtins (void) terminal_encodings_get_builtins (void)
{ {
GHashTable *encodings_hashtable; GHashTable *encodings_hashtable;
guint i; guint i;
TerminalEncoding *encoding; TerminalEncoding *encoding;
encodings_hashtable = g_hash_table_new_full (g_str_hash, g_str_equal, encodings_hashtable = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, NULL,
(GDestroyNotify) terminal_encoding_unref); (GDestroyNotify) terminal_encoding_unref);
/* Placeholder entry for the current locale's charset */ /* Placeholder entry for the current locale's charset */
encoding = terminal_encoding_new ("current", encoding = terminal_encoding_new ("current",
_("Current Locale"), _("Current Locale"),
FALSE, FALSE,
TRUE); TRUE);
g_hash_table_insert (encodings_hashtable, g_hash_table_insert (encodings_hashtable,
(gpointer) terminal_encoding_get_id (encoding), (gpointer) terminal_encoding_get_id (encoding),
encoding); encoding);
for (i = 0; i < G_N_ELEMENTS (encodings); ++i) for (i = 0; i < G_N_ELEMENTS (encodings); ++i)
{ {
encoding = terminal_encoding_new (encodings[i].charset, encoding = terminal_encoding_new (encodings[i].charset,
_(encodings[i].name), _(encodings[i].name),
FALSE, FALSE,
FALSE); FALSE);
g_hash_table_insert (encodings_hashtable, g_hash_table_insert (encodings_hashtable,
(gpointer) terminal_encoding_get_id (encoding), (gpointer) terminal_encoding_get_id (encoding),
encoding); encoding);
} }
return encodings_hashtable; return encodings_hashtable;
} }

View File

@ -28,21 +28,21 @@
typedef struct typedef struct
{ {
int refcount; int refcount;
char *id; char *id;
char *name; char *name;
guint valid : 1; guint valid : 1;
guint validity_checked : 1; guint validity_checked : 1;
guint is_custom : 1; guint is_custom : 1;
guint is_active : 1; guint is_active : 1;
} TerminalEncoding; } TerminalEncoding;
GType terminal_encoding_get_type (void); GType terminal_encoding_get_type (void);
TerminalEncoding *terminal_encoding_new (const char *charset, TerminalEncoding *terminal_encoding_new (const char *charset,
const char *display_name, const char *display_name,
gboolean is_custom, gboolean is_custom,
gboolean force_valid); gboolean force_valid);
TerminalEncoding *terminal_encoding_ref (TerminalEncoding *encoding); TerminalEncoding *terminal_encoding_ref (TerminalEncoding *encoding);

View File

@ -26,7 +26,7 @@
struct _TerminalInfoBarPrivate struct _TerminalInfoBarPrivate
{ {
GtkWidget *content_box; GtkWidget *content_box;
}; };
G_DEFINE_TYPE (TerminalInfoBar, terminal_info_bar, GTK_TYPE_INFO_BAR) G_DEFINE_TYPE (TerminalInfoBar, terminal_info_bar, GTK_TYPE_INFO_BAR)
@ -36,22 +36,22 @@ G_DEFINE_TYPE (TerminalInfoBar, terminal_info_bar, GTK_TYPE_INFO_BAR)
static void static void
terminal_info_bar_init (TerminalInfoBar *bar) terminal_info_bar_init (TerminalInfoBar *bar)
{ {
GtkInfoBar *info_bar = GTK_INFO_BAR (bar); GtkInfoBar *info_bar = GTK_INFO_BAR (bar);
TerminalInfoBarPrivate *priv; TerminalInfoBarPrivate *priv;
priv = bar->priv = TERMINAL_INFO_BAR_GET_PRIVATE (bar); priv = bar->priv = TERMINAL_INFO_BAR_GET_PRIVATE (bar);
priv->content_box = gtk_vbox_new (FALSE, 6); priv->content_box = gtk_vbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (info_bar)), gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (info_bar)),
priv->content_box, TRUE, TRUE, 0); priv->content_box, TRUE, TRUE, 0);
} }
static void static void
terminal_info_bar_class_init (TerminalInfoBarClass *klass) terminal_info_bar_class_init (TerminalInfoBarClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (gobject_class, sizeof (TerminalInfoBarPrivate)); g_type_class_add_private (gobject_class, sizeof (TerminalInfoBarPrivate));
} }
/* public API */ /* public API */
@ -67,26 +67,27 @@ terminal_info_bar_new (GtkMessageType type,
const char *first_button_text, const char *first_button_text,
...) ...)
{ {
GtkWidget *info_bar; GtkWidget *info_bar;
va_list args; va_list args;
info_bar = g_object_new (TERMINAL_TYPE_INFO_BAR, info_bar = g_object_new (TERMINAL_TYPE_INFO_BAR,
"message-type", type, "message-type", type,
NULL); NULL);
va_start (args, first_button_text); va_start (args, first_button_text);
while (first_button_text != NULL) { while (first_button_text != NULL)
int response_id; {
int response_id;
response_id = va_arg (args, int); response_id = va_arg (args, int);
gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
first_button_text, response_id); first_button_text, response_id);
first_button_text = va_arg (args, const char *); first_button_text = va_arg (args, const char *);
} }
va_end (args); va_end (args);
return info_bar; return info_bar;
} }
void void
@ -94,26 +95,26 @@ terminal_info_bar_format_text (TerminalInfoBar *bar,
const char *format, const char *format,
...) ...)
{ {
TerminalInfoBarPrivate *priv; TerminalInfoBarPrivate *priv;
char *text; char *text;
GtkWidget *label; GtkWidget *label;
va_list args; va_list args;
g_return_if_fail (TERMINAL_IS_INFO_BAR (bar)); g_return_if_fail (TERMINAL_IS_INFO_BAR (bar));
priv = bar->priv; priv = bar->priv;
va_start (args, format); va_start (args, format);
text = g_strdup_vprintf (format, args); text = g_strdup_vprintf (format, args);
va_end (args); va_end (args);
label = gtk_label_new (text); label = gtk_label_new (text);
g_free (text); g_free (text);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
gtk_box_pack_start (GTK_BOX (priv->content_box), label, FALSE, FALSE, 0); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_widget_show_all (priv->content_box); gtk_label_set_selectable (GTK_LABEL (label), TRUE);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
gtk_box_pack_start (GTK_BOX (priv->content_box), label, FALSE, FALSE, 0);
gtk_widget_show_all (priv->content_box);
} }

View File

@ -36,15 +36,15 @@ typedef struct _TerminalInfoBarPrivate TerminalInfoBarPrivate;
struct _TerminalInfoBar struct _TerminalInfoBar
{ {
GtkInfoBar parent_instance; GtkInfoBar parent_instance;
/*< private >*/ /*< private >*/
TerminalInfoBarPrivate *priv; TerminalInfoBarPrivate *priv;
}; };
struct _TerminalInfoBarClass struct _TerminalInfoBarClass
{ {
GtkInfoBarClass parent_class; GtkInfoBarClass parent_class;
}; };
GType terminal_info_bar_get_type (void); GType terminal_info_bar_get_type (void);

File diff suppressed because it is too large Load Diff

View File

@ -28,81 +28,82 @@ G_BEGIN_DECLS
typedef struct typedef struct
{ {
gboolean remote_arguments; gboolean remote_arguments;
char **env; char **env;
char *startup_id; char *startup_id;
char *display_name; char *display_name;
int screen_number; int screen_number;
GList *initial_windows; GList *initial_windows;
gboolean default_window_menubar_forced; gboolean default_window_menubar_forced;
gboolean default_window_menubar_state; gboolean default_window_menubar_state;
gboolean default_fullscreen; gboolean default_fullscreen;
gboolean default_maximize; gboolean default_maximize;
char *default_role; char *default_role;
char *default_geometry; char *default_geometry;
char *default_working_dir; char *default_working_dir;
char *default_title; char *default_title;
char **exec_argv; char **exec_argv;
char *default_profile; char *default_profile;
gboolean default_profile_is_id; gboolean default_profile_is_id;
gboolean execute; gboolean execute;
gboolean use_factory; gboolean use_factory;
double zoom; double zoom;
char *config_file; char *config_file;
gboolean load_config; gboolean load_config;
gboolean save_config; gboolean save_config;
} TerminalOptions; } TerminalOptions;
typedef struct typedef struct
{ {
char *profile; char *profile;
gboolean profile_is_id; gboolean profile_is_id;
char **exec_argv; char **exec_argv;
char *title; char *title;
char *working_dir; char *working_dir;
double zoom; double zoom;
guint zoom_set : 1; guint zoom_set : 1;
guint active : 1; guint active : 1;
} InitialTab; } InitialTab;
typedef struct typedef struct
{ {
guint source_tag; guint source_tag;
GList *tabs; /* list of InitialTab */ GList *tabs; /* list of InitialTab */
gboolean force_menubar_state; gboolean force_menubar_state;
gboolean menubar_state; gboolean menubar_state;
gboolean start_fullscreen; gboolean start_fullscreen;
gboolean start_maximized; gboolean start_maximized;
char *geometry; char *geometry;
char *role; char *role;
} InitialWindow; } InitialWindow;
#define TERMINAL_OPTION_ERROR (g_quark_from_static_string ("terminal-option-error")) #define TERMINAL_OPTION_ERROR (g_quark_from_static_string ("terminal-option-error"))
typedef enum { typedef enum
TERMINAL_OPTION_ERROR_NOT_IN_FACTORY, {
TERMINAL_OPTION_ERROR_EXCLUSIVE_OPTIONS, TERMINAL_OPTION_ERROR_NOT_IN_FACTORY,
TERMINAL_OPTION_ERROR_INVALID_CONFIG_FILE, TERMINAL_OPTION_ERROR_EXCLUSIVE_OPTIONS,
TERMINAL_OPTION_ERROR_INCOMPATIBLE_CONFIG_FILE TERMINAL_OPTION_ERROR_INVALID_CONFIG_FILE,
TERMINAL_OPTION_ERROR_INCOMPATIBLE_CONFIG_FILE
} TerminalOptionError; } TerminalOptionError;
TerminalOptions *terminal_options_parse (const char *working_directory, TerminalOptions *terminal_options_parse (const char *working_directory,
const char *display_name, const char *display_name,
const char *startup_id, const char *startup_id,
char **env, char **env,
gboolean remote_arguments, gboolean remote_arguments,
gboolean ignore_unknown_options, gboolean ignore_unknown_options,
int *argcp, int *argcp,
char ***argvp, char ***argvp,
GError **error, GError **error,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
gboolean terminal_options_merge_config (TerminalOptions *options, gboolean terminal_options_merge_config (TerminalOptions *options,
GKeyFile *key_file, GKeyFile *key_file,

File diff suppressed because it is too large Load Diff

View File

@ -28,32 +28,32 @@ G_BEGIN_DECLS
typedef enum typedef enum
{ {
/* this has to be kept in sync with the option menu in the profile editor UI file */ /* this has to be kept in sync with the option menu in the profile editor UI file */
TERMINAL_TITLE_REPLACE, TERMINAL_TITLE_REPLACE,
TERMINAL_TITLE_BEFORE, TERMINAL_TITLE_BEFORE,
TERMINAL_TITLE_AFTER, TERMINAL_TITLE_AFTER,
TERMINAL_TITLE_IGNORE TERMINAL_TITLE_IGNORE
} TerminalTitleMode; } TerminalTitleMode;
typedef enum typedef enum
{ {
TERMINAL_SCROLLBAR_LEFT, TERMINAL_SCROLLBAR_LEFT,
TERMINAL_SCROLLBAR_RIGHT, TERMINAL_SCROLLBAR_RIGHT,
TERMINAL_SCROLLBAR_HIDDEN TERMINAL_SCROLLBAR_HIDDEN
} TerminalScrollbarPosition; } TerminalScrollbarPosition;
typedef enum typedef enum
{ {
TERMINAL_EXIT_CLOSE, TERMINAL_EXIT_CLOSE,
TERMINAL_EXIT_RESTART, TERMINAL_EXIT_RESTART,
TERMINAL_EXIT_HOLD TERMINAL_EXIT_HOLD
} TerminalExitAction; } TerminalExitAction;
typedef enum typedef enum
{ {
TERMINAL_BACKGROUND_SOLID, TERMINAL_BACKGROUND_SOLID,
TERMINAL_BACKGROUND_IMAGE, TERMINAL_BACKGROUND_IMAGE,
TERMINAL_BACKGROUND_TRANSPARENT TERMINAL_BACKGROUND_TRANSPARENT
} TerminalBackgroundType; } TerminalBackgroundType;
#define TERMINAL_PALETTE_SIZE 16 #define TERMINAL_PALETTE_SIZE 16
@ -120,18 +120,18 @@ typedef struct _TerminalProfilePrivate TerminalProfilePrivate;
struct _TerminalProfile struct _TerminalProfile
{ {
GObject parent_instance; GObject parent_instance;
TerminalProfilePrivate *priv; TerminalProfilePrivate *priv;
}; };
struct _TerminalProfileClass struct _TerminalProfileClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
void (* forgotten) (TerminalProfile *profile); void (* forgotten) (TerminalProfile *profile);
GHashTable *mateconf_keys; GHashTable *mateconf_keys;
}; };
GType terminal_profile_get_type (void); GType terminal_profile_get_type (void);
@ -143,48 +143,48 @@ void _terminal_profile_forget (TerminalProfile *prof
gboolean _terminal_profile_get_forgotten (TerminalProfile *profile); gboolean _terminal_profile_get_forgotten (TerminalProfile *profile);
TerminalProfile* _terminal_profile_clone (TerminalProfile *base_profile, TerminalProfile* _terminal_profile_clone (TerminalProfile *base_profile,
const char *visible_name); const char *visible_name);
gboolean terminal_profile_property_locked (TerminalProfile *profile, gboolean terminal_profile_property_locked (TerminalProfile *profile,
const char *prop_name); const char *prop_name);
void terminal_profile_reset_property (TerminalProfile *profile, void terminal_profile_reset_property (TerminalProfile *profile,
const char *prop_name); const char *prop_name);
gboolean terminal_profile_get_property_boolean (TerminalProfile *profile, gboolean terminal_profile_get_property_boolean (TerminalProfile *profile,
const char *prop_name); const char *prop_name);
gconstpointer terminal_profile_get_property_boxed (TerminalProfile *profile, gconstpointer terminal_profile_get_property_boxed (TerminalProfile *profile,
const char *prop_name); const char *prop_name);
double terminal_profile_get_property_double (TerminalProfile *profile, double terminal_profile_get_property_double (TerminalProfile *profile,
const char *prop_name); const char *prop_name);
int terminal_profile_get_property_enum (TerminalProfile *profile, int terminal_profile_get_property_enum (TerminalProfile *profile,
const char *prop_name); const char *prop_name);
int terminal_profile_get_property_int (TerminalProfile *profile, int terminal_profile_get_property_int (TerminalProfile *profile,
const char *prop_name); const char *prop_name);
gpointer terminal_profile_get_property_object (TerminalProfile *profile, gpointer terminal_profile_get_property_object (TerminalProfile *profile,
const char *prop_name); const char *prop_name);
const char* terminal_profile_get_property_string (TerminalProfile *profile, const char* terminal_profile_get_property_string (TerminalProfile *profile,
const char *prop_name); const char *prop_name);
gboolean terminal_profile_get_palette (TerminalProfile *profile, gboolean terminal_profile_get_palette (TerminalProfile *profile,
GdkColor *colors, GdkColor *colors,
guint *n_colors); guint *n_colors);
gboolean terminal_profile_get_palette_is_builtin (TerminalProfile *profile, gboolean terminal_profile_get_palette_is_builtin (TerminalProfile *profile,
guint *n); guint *n);
void terminal_profile_set_palette_builtin (TerminalProfile *profile, void terminal_profile_set_palette_builtin (TerminalProfile *profile,
guint n); guint n);
gboolean terminal_profile_modify_palette_entry (TerminalProfile *profile, gboolean terminal_profile_modify_palette_entry (TerminalProfile *profile,
guint i, guint i,
const GdkColor *color); const GdkColor *color);
G_END_DECLS G_END_DECLS

View File

@ -29,27 +29,27 @@
struct _TerminalScreenContainerPrivate struct _TerminalScreenContainerPrivate
{ {
TerminalScreen *screen; TerminalScreen *screen;
#ifdef USE_SCROLLED_WINDOW #ifdef USE_SCROLLED_WINDOW
GtkWidget *scrolled_window; GtkWidget *scrolled_window;
#else #else
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *vscrollbar; GtkWidget *vscrollbar;
#endif #endif
GtkPolicyType hscrollbar_policy; GtkPolicyType hscrollbar_policy;
GtkPolicyType vscrollbar_policy; GtkPolicyType vscrollbar_policy;
GtkCornerType window_placement; GtkCornerType window_placement;
guint window_placement_set : 1; guint window_placement_set : 1;
}; };
enum enum
{ {
PROP_0, PROP_0,
PROP_SCREEN, PROP_SCREEN,
PROP_HSCROLLBAR_POLICY, PROP_HSCROLLBAR_POLICY,
PROP_VSCROLLBAR_POLICY, PROP_VSCROLLBAR_POLICY,
PROP_WINDOW_PLACEMENT, PROP_WINDOW_PLACEMENT,
PROP_WINDOW_PLACEMENT_SET PROP_WINDOW_PLACEMENT_SET
}; };
G_DEFINE_TYPE (TerminalScreenContainer, terminal_screen_container, GTK_TYPE_VBOX) G_DEFINE_TYPE (TerminalScreenContainer, terminal_screen_container, GTK_TYPE_VBOX)
@ -58,43 +58,44 @@ G_DEFINE_TYPE (TerminalScreenContainer, terminal_screen_container, GTK_TYPE_VBOX
static void static void
terminal_screen_container_set_placement_internal (TerminalScreenContainer *container, terminal_screen_container_set_placement_internal (TerminalScreenContainer *container,
GtkCornerType corner) GtkCornerType corner)
{ {
TerminalScreenContainerPrivate *priv = container->priv; TerminalScreenContainerPrivate *priv = container->priv;
#ifdef USE_SCROLLED_WINDOW #ifdef USE_SCROLLED_WINDOW
gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (priv->scrolled_window), corner); gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (priv->scrolled_window), corner);
#else #else
switch (corner) { switch (corner)
case GTK_CORNER_TOP_LEFT: {
case GTK_CORNER_BOTTOM_LEFT: case GTK_CORNER_TOP_LEFT:
gtk_box_reorder_child (GTK_BOX (priv->hbox), priv->vscrollbar, 1); case GTK_CORNER_BOTTOM_LEFT:
break; gtk_box_reorder_child (GTK_BOX (priv->hbox), priv->vscrollbar, 1);
case GTK_CORNER_TOP_RIGHT: break;
case GTK_CORNER_BOTTOM_RIGHT: case GTK_CORNER_TOP_RIGHT:
gtk_box_reorder_child (GTK_BOX (priv->hbox), priv->vscrollbar, 0); case GTK_CORNER_BOTTOM_RIGHT:
break; gtk_box_reorder_child (GTK_BOX (priv->hbox), priv->vscrollbar, 0);
default: break;
g_assert_not_reached (); default:
} g_assert_not_reached ();
}
#endif #endif
priv->window_placement = corner; priv->window_placement = corner;
g_object_notify (G_OBJECT (container), "window-placement"); g_object_notify (G_OBJECT (container), "window-placement");
} }
static void static void
terminal_screen_container_set_placement_set (TerminalScreenContainer *container, terminal_screen_container_set_placement_set (TerminalScreenContainer *container,
gboolean set) gboolean set)
{ {
TerminalScreenContainerPrivate *priv = container->priv; TerminalScreenContainerPrivate *priv = container->priv;
#ifdef USE_SCROLLED_WINDOW #ifdef USE_SCROLLED_WINDOW
g_object_set (priv->scrolled_window, "window-placement-set", set, NULL); g_object_set (priv->scrolled_window, "window-placement-set", set, NULL);
#endif #endif
priv->window_placement_set = set != FALSE; priv->window_placement_set = set != FALSE;
g_object_notify (G_OBJECT (container), "window-placement-set"); g_object_notify (G_OBJECT (container), "window-placement-set");
} }
#if defined(USE_SCROLLED_WINDOW) && defined(MATE_ENABLE_DEBUG) #if defined(USE_SCROLLED_WINDOW) && defined(MATE_ENABLE_DEBUG)
@ -103,9 +104,9 @@ size_request_cb (GtkWidget *widget,
GtkRequisition *req, GtkRequisition *req,
TerminalScreenContainer *container) TerminalScreenContainer *container)
{ {
_terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
"[screen %p] scrolled-window size req %d : %d\n", "[screen %p] scrolled-window size req %d : %d\n",
container->priv->screen, req->width, req->height); container->priv->screen, req->width, req->height);
} }
#endif #endif
@ -114,66 +115,66 @@ size_request_cb (GtkWidget *widget,
static void static void
terminal_screen_container_init (TerminalScreenContainer *container) terminal_screen_container_init (TerminalScreenContainer *container)
{ {
TerminalScreenContainerPrivate *priv; TerminalScreenContainerPrivate *priv;
priv = container->priv = TERMINAL_SCREEN_CONTAINER_GET_PRIVATE (container); priv = container->priv = TERMINAL_SCREEN_CONTAINER_GET_PRIVATE (container);
priv->hscrollbar_policy = GTK_POLICY_AUTOMATIC; priv->hscrollbar_policy = GTK_POLICY_AUTOMATIC;
priv->vscrollbar_policy = GTK_POLICY_AUTOMATIC; priv->vscrollbar_policy = GTK_POLICY_AUTOMATIC;
priv->window_placement = GTK_CORNER_BOTTOM_RIGHT; priv->window_placement = GTK_CORNER_BOTTOM_RIGHT;
priv->window_placement_set = FALSE; priv->window_placement_set = FALSE;
} }
static GObject * static GObject *
terminal_screen_container_constructor (GType type, terminal_screen_container_constructor (GType type,
guint n_construct_properties, guint n_construct_properties,
GObjectConstructParam *construct_params) GObjectConstructParam *construct_params)
{ {
GObject *object; GObject *object;
TerminalScreenContainer *container; TerminalScreenContainer *container;
TerminalScreenContainerPrivate *priv; TerminalScreenContainerPrivate *priv;
object = G_OBJECT_CLASS (terminal_screen_container_parent_class)->constructor object = G_OBJECT_CLASS (terminal_screen_container_parent_class)->constructor
(type, n_construct_properties, construct_params); (type, n_construct_properties, construct_params);
container = TERMINAL_SCREEN_CONTAINER (object); container = TERMINAL_SCREEN_CONTAINER (object);
priv = container->priv; priv = container->priv;
g_assert (priv->screen != NULL); g_assert (priv->screen != NULL);
#ifdef USE_SCROLLED_WINDOW #ifdef USE_SCROLLED_WINDOW
priv->scrolled_window = gtk_scrolled_window_new (NULL, vte_terminal_get_adjustment (VTE_TERMINAL (priv->screen))); priv->scrolled_window = gtk_scrolled_window_new (NULL, vte_terminal_get_adjustment (VTE_TERMINAL (priv->screen)));
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window),
priv->hscrollbar_policy, priv->hscrollbar_policy,
priv->vscrollbar_policy); priv->vscrollbar_policy);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scrolled_window), gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scrolled_window),
GTK_SHADOW_NONE); GTK_SHADOW_NONE);
gtk_container_add (GTK_CONTAINER (priv->scrolled_window), GTK_WIDGET (priv->screen)); gtk_container_add (GTK_CONTAINER (priv->scrolled_window), GTK_WIDGET (priv->screen));
gtk_widget_show (GTK_WIDGET (priv->screen)); gtk_widget_show (GTK_WIDGET (priv->screen));
gtk_box_pack_end (GTK_BOX (container), priv->scrolled_window, TRUE, TRUE, 0); gtk_box_pack_end (GTK_BOX (container), priv->scrolled_window, TRUE, TRUE, 0);
gtk_widget_show (priv->scrolled_window); gtk_widget_show (priv->scrolled_window);
#ifdef MATE_ENABLE_DEBUG #ifdef MATE_ENABLE_DEBUG
g_signal_connect (priv->scrolled_window, "size-request", G_CALLBACK (size_request_cb), container); g_signal_connect (priv->scrolled_window, "size-request", G_CALLBACK (size_request_cb), container);
#endif #endif
#else #else
priv->hbox = gtk_hbox_new (FALSE, 0); priv->hbox = gtk_hbox_new (FALSE, 0);
priv->vscrollbar = gtk_vscrollbar_new (vte_terminal_get_adjustment (VTE_TERMINAL (priv->screen))); priv->vscrollbar = gtk_vscrollbar_new (vte_terminal_get_adjustment (VTE_TERMINAL (priv->screen)));
gtk_box_pack_start (GTK_BOX (priv->hbox), GTK_WIDGET (priv->screen), TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (priv->hbox), GTK_WIDGET (priv->screen), TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (priv->hbox), priv->vscrollbar, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (priv->hbox), priv->vscrollbar, FALSE, FALSE, 0);
gtk_box_pack_end (GTK_BOX (container), priv->hbox, TRUE, TRUE, 0); gtk_box_pack_end (GTK_BOX (container), priv->hbox, TRUE, TRUE, 0);
gtk_widget_show_all (priv->hbox); gtk_widget_show_all (priv->hbox);
#endif /* USE_SCROLLED_WINDOW */ #endif /* USE_SCROLLED_WINDOW */
_terminal_screen_update_scrollbar (priv->screen); _terminal_screen_update_scrollbar (priv->screen);
return object; return object;
} }
static void static void
@ -182,28 +183,29 @@ terminal_screen_container_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (object); TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (object);
TerminalScreenContainerPrivate *priv = container->priv; TerminalScreenContainerPrivate *priv = container->priv;
switch (prop_id) { switch (prop_id)
case PROP_SCREEN: {
break; case PROP_SCREEN:
case PROP_HSCROLLBAR_POLICY: break;
g_value_set_enum (value, priv->hscrollbar_policy); case PROP_HSCROLLBAR_POLICY:
break; g_value_set_enum (value, priv->hscrollbar_policy);
case PROP_VSCROLLBAR_POLICY: break;
g_value_set_enum (value, priv->vscrollbar_policy); case PROP_VSCROLLBAR_POLICY:
break; g_value_set_enum (value, priv->vscrollbar_policy);
case PROP_WINDOW_PLACEMENT: break;
g_value_set_enum (value, priv->window_placement); case PROP_WINDOW_PLACEMENT:
break; g_value_set_enum (value, priv->window_placement);
case PROP_WINDOW_PLACEMENT_SET: break;
g_value_set_boolean (value, priv->window_placement_set); case PROP_WINDOW_PLACEMENT_SET:
break; g_value_set_boolean (value, priv->window_placement_set);
default: break;
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); default:
break; G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} break;
}
} }
static void static void
@ -212,88 +214,89 @@ terminal_screen_container_set_property (GObject *object,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (object); TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (object);
TerminalScreenContainerPrivate *priv = container->priv; TerminalScreenContainerPrivate *priv = container->priv;
switch (prop_id) { switch (prop_id)
case PROP_SCREEN: {
priv->screen = g_value_get_object (value); case PROP_SCREEN:
break; priv->screen = g_value_get_object (value);
case PROP_HSCROLLBAR_POLICY: break;
terminal_screen_container_set_policy (container, case PROP_HSCROLLBAR_POLICY:
g_value_get_enum (value), terminal_screen_container_set_policy (container,
priv->vscrollbar_policy); g_value_get_enum (value),
break; priv->vscrollbar_policy);
case PROP_VSCROLLBAR_POLICY: break;
terminal_screen_container_set_policy (container, case PROP_VSCROLLBAR_POLICY:
priv->hscrollbar_policy, terminal_screen_container_set_policy (container,
g_value_get_enum (value)); priv->hscrollbar_policy,
break; g_value_get_enum (value));
case PROP_WINDOW_PLACEMENT: break;
terminal_screen_container_set_placement_internal (container, g_value_get_enum (value)); case PROP_WINDOW_PLACEMENT:
break; terminal_screen_container_set_placement_internal (container, g_value_get_enum (value));
case PROP_WINDOW_PLACEMENT_SET: break;
terminal_screen_container_set_placement_set (container, g_value_get_boolean (value)); case PROP_WINDOW_PLACEMENT_SET:
break; terminal_screen_container_set_placement_set (container, g_value_get_boolean (value));
default: break;
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); default:
break; G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} break;
}
} }
static void static void
terminal_screen_container_class_init (TerminalScreenContainerClass *klass) terminal_screen_container_class_init (TerminalScreenContainerClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (gobject_class, sizeof (TerminalScreenContainerPrivate)); g_type_class_add_private (gobject_class, sizeof (TerminalScreenContainerPrivate));
gobject_class->constructor = terminal_screen_container_constructor; gobject_class->constructor = terminal_screen_container_constructor;
gobject_class->get_property = terminal_screen_container_get_property; gobject_class->get_property = terminal_screen_container_get_property;
gobject_class->set_property = terminal_screen_container_set_property; gobject_class->set_property = terminal_screen_container_set_property;
g_object_class_install_property g_object_class_install_property
(gobject_class, (gobject_class,
PROP_SCREEN, PROP_SCREEN,
g_param_spec_object ("screen", NULL, NULL, g_param_spec_object ("screen", NULL, NULL,
TERMINAL_TYPE_SCREEN, TERMINAL_TYPE_SCREEN,
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
g_object_class_install_property g_object_class_install_property
(gobject_class, (gobject_class,
PROP_HSCROLLBAR_POLICY, PROP_HSCROLLBAR_POLICY,
g_param_spec_enum ("hscrollbar-policy", NULL, NULL, g_param_spec_enum ("hscrollbar-policy", NULL, NULL,
GTK_TYPE_POLICY_TYPE, GTK_TYPE_POLICY_TYPE,
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
g_object_class_install_property g_object_class_install_property
(gobject_class, (gobject_class,
PROP_VSCROLLBAR_POLICY, PROP_VSCROLLBAR_POLICY,
g_param_spec_enum ("vscrollbar-policy", NULL, NULL, g_param_spec_enum ("vscrollbar-policy", NULL, NULL,
GTK_TYPE_POLICY_TYPE, GTK_TYPE_POLICY_TYPE,
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
g_object_class_install_property g_object_class_install_property
(gobject_class, (gobject_class,
PROP_WINDOW_PLACEMENT, PROP_WINDOW_PLACEMENT,
g_param_spec_enum ("window-placement", NULL, NULL, g_param_spec_enum ("window-placement", NULL, NULL,
GTK_TYPE_CORNER_TYPE, GTK_TYPE_CORNER_TYPE,
GTK_CORNER_TOP_LEFT, GTK_CORNER_TOP_LEFT,
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
g_object_class_install_property g_object_class_install_property
(gobject_class, (gobject_class,
PROP_WINDOW_PLACEMENT_SET, PROP_WINDOW_PLACEMENT_SET,
g_param_spec_boolean ("window-placement-set", NULL, NULL, g_param_spec_boolean ("window-placement-set", NULL, NULL,
FALSE, FALSE,
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
} }
/* public API */ /* public API */
@ -307,9 +310,9 @@ terminal_screen_container_class_init (TerminalScreenContainerClass *klass)
GtkWidget * GtkWidget *
terminal_screen_container_new (TerminalScreen *screen) terminal_screen_container_new (TerminalScreen *screen)
{ {
return g_object_new (TERMINAL_TYPE_SCREEN_CONTAINER, return g_object_new (TERMINAL_TYPE_SCREEN_CONTAINER,
"screen", screen, "screen", screen,
NULL); NULL);
} }
/** /**
@ -321,9 +324,9 @@ terminal_screen_container_new (TerminalScreen *screen)
TerminalScreen * TerminalScreen *
terminal_screen_container_get_screen (TerminalScreenContainer *container) terminal_screen_container_get_screen (TerminalScreenContainer *container)
{ {
g_return_val_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container), NULL); g_return_val_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container), NULL);
return container->priv->screen; return container->priv->screen;
} }
/** /**
@ -335,9 +338,9 @@ terminal_screen_container_get_screen (TerminalScreenContainer *container)
TerminalScreenContainer * TerminalScreenContainer *
terminal_screen_container_get_from_screen (TerminalScreen *screen) terminal_screen_container_get_from_screen (TerminalScreen *screen)
{ {
g_return_val_if_fail (TERMINAL_IS_SCREEN (screen), NULL); g_return_val_if_fail (TERMINAL_IS_SCREEN (screen), NULL);
return TERMINAL_SCREEN_CONTAINER (gtk_widget_get_ancestor (GTK_WIDGET (screen), TERMINAL_TYPE_SCREEN_CONTAINER)); return TERMINAL_SCREEN_CONTAINER (gtk_widget_get_ancestor (GTK_WIDGET (screen), TERMINAL_TYPE_SCREEN_CONTAINER));
} }
/** /**
@ -353,42 +356,45 @@ terminal_screen_container_set_policy (TerminalScreenContainer *container,
GtkPolicyType hpolicy G_GNUC_UNUSED, GtkPolicyType hpolicy G_GNUC_UNUSED,
GtkPolicyType vpolicy) GtkPolicyType vpolicy)
{ {
TerminalScreenContainerPrivate *priv; TerminalScreenContainerPrivate *priv;
GObject *object; GObject *object;
g_return_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container)); g_return_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container));
object = G_OBJECT (container); object = G_OBJECT (container);
priv = container->priv; priv = container->priv;
g_object_freeze_notify (object); g_object_freeze_notify (object);
if (priv->hscrollbar_policy != hpolicy) { if (priv->hscrollbar_policy != hpolicy)
priv->hscrollbar_policy = hpolicy; {
g_object_notify (object, "hscrollbar-policy"); priv->hscrollbar_policy = hpolicy;
} g_object_notify (object, "hscrollbar-policy");
if (priv->vscrollbar_policy != vpolicy) { }
priv->vscrollbar_policy = vpolicy; if (priv->vscrollbar_policy != vpolicy)
g_object_notify (object, "vscrollbar-policy"); {
} priv->vscrollbar_policy = vpolicy;
g_object_notify (object, "vscrollbar-policy");
}
#ifdef USE_SCROLLED_WINDOW #ifdef USE_SCROLLED_WINDOW
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window), hpolicy, vpolicy); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window), hpolicy, vpolicy);
#else #else
switch (vpolicy) { switch (vpolicy)
case GTK_POLICY_NEVER: {
gtk_widget_hide (priv->vscrollbar); case GTK_POLICY_NEVER:
break; gtk_widget_hide (priv->vscrollbar);
case GTK_POLICY_AUTOMATIC: break;
case GTK_POLICY_ALWAYS: case GTK_POLICY_AUTOMATIC:
gtk_widget_show (priv->vscrollbar); case GTK_POLICY_ALWAYS:
break; gtk_widget_show (priv->vscrollbar);
default: break;
g_assert_not_reached (); default:
} g_assert_not_reached ();
}
#endif #endif
g_object_thaw_notify (object); g_object_thaw_notify (object);
} }
/** /**
@ -400,10 +406,10 @@ terminal_screen_container_set_policy (TerminalScreenContainer *container,
*/ */
void void
terminal_screen_container_set_placement (TerminalScreenContainer *container, terminal_screen_container_set_placement (TerminalScreenContainer *container,
GtkCornerType corner) GtkCornerType corner)
{ {
g_return_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container)); g_return_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container));
terminal_screen_container_set_placement_internal (container, corner); terminal_screen_container_set_placement_internal (container, corner);
terminal_screen_container_set_placement_set (container, TRUE); terminal_screen_container_set_placement_set (container, TRUE);
} }

View File

@ -38,15 +38,15 @@ typedef struct _TerminalScreenContainerPrivate TerminalScreenContainerPrivate;
struct _TerminalScreenContainer struct _TerminalScreenContainer
{ {
GtkVBox parent_instance; GtkVBox parent_instance;
/*< private >*/ /*< private >*/
TerminalScreenContainerPrivate *priv; TerminalScreenContainerPrivate *priv;
}; };
struct _TerminalScreenContainerClass struct _TerminalScreenContainerClass
{ {
GtkVBoxClass parent_class; GtkVBoxClass parent_class;
}; };
GType terminal_screen_container_get_type (void); GType terminal_screen_container_get_type (void);
@ -58,11 +58,11 @@ TerminalScreen *terminal_screen_container_get_screen (TerminalScreenContainer *c
TerminalScreenContainer *terminal_screen_container_get_from_screen (TerminalScreen *screen); TerminalScreenContainer *terminal_screen_container_get_from_screen (TerminalScreen *screen);
void terminal_screen_container_set_policy (TerminalScreenContainer *container, void terminal_screen_container_set_policy (TerminalScreenContainer *container,
GtkPolicyType hpolicy, GtkPolicyType hpolicy,
GtkPolicyType vpolicy); GtkPolicyType vpolicy);
void terminal_screen_container_set_placement (TerminalScreenContainer *container, void terminal_screen_container_set_placement (TerminalScreenContainer *container,
GtkCornerType corner); GtkCornerType corner);
G_END_DECLS G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@ -27,12 +27,13 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum { typedef enum
FLAVOR_AS_IS, {
FLAVOR_DEFAULT_TO_HTTP, FLAVOR_AS_IS,
FLAVOR_VOIP_CALL, FLAVOR_DEFAULT_TO_HTTP,
FLAVOR_EMAIL, FLAVOR_VOIP_CALL,
FLAVOR_SKEY FLAVOR_EMAIL,
FLAVOR_SKEY
} TerminalURLFlavour; } TerminalURLFlavour;
/* Forward decls */ /* Forward decls */
@ -52,24 +53,24 @@ typedef struct _TerminalScreenPrivate TerminalScreenPrivate;
struct _TerminalScreen struct _TerminalScreen
{ {
VteTerminal parent_instance; VteTerminal parent_instance;
TerminalScreenPrivate *priv; TerminalScreenPrivate *priv;
}; };
struct _TerminalScreenClass struct _TerminalScreenClass
{ {
VteTerminalClass parent_class; VteTerminalClass parent_class;
void (* profile_set) (TerminalScreen *screen, void (* profile_set) (TerminalScreen *screen,
TerminalProfile *old_profile); TerminalProfile *old_profile);
void (* show_popup_menu) (TerminalScreen *screen, void (* show_popup_menu) (TerminalScreen *screen,
TerminalScreenPopupInfo *info); TerminalScreenPopupInfo *info);
gboolean (* match_clicked) (TerminalScreen *screen, gboolean (* match_clicked) (TerminalScreen *screen,
const char *url, const char *url,
int flavour, int flavour,
guint state); guint state);
void (* close_screen) (TerminalScreen *screen); void (* close_screen) (TerminalScreen *screen);
}; };
GType terminal_screen_get_type (void) G_GNUC_CONST; GType terminal_screen_get_type (void) G_GNUC_CONST;
@ -86,11 +87,11 @@ void terminal_screen_set_profile (TerminalScreen *screen,
TerminalProfile* terminal_screen_get_profile (TerminalScreen *screen); TerminalProfile* terminal_screen_get_profile (TerminalScreen *screen);
void terminal_screen_set_override_command (TerminalScreen *screen, void terminal_screen_set_override_command (TerminalScreen *screen,
char **argv); char **argv);
const char** terminal_screen_get_override_command (TerminalScreen *screen); const char** terminal_screen_get_override_command (TerminalScreen *screen);
void terminal_screen_set_initial_environment (TerminalScreen *screen, void terminal_screen_set_initial_environment (TerminalScreen *screen,
char **argv); char **argv);
char ** terminal_screen_get_initial_environment (TerminalScreen *screen); char ** terminal_screen_get_initial_environment (TerminalScreen *screen);
const char* terminal_screen_get_raw_title (TerminalScreen *screen); const char* terminal_screen_get_raw_title (TerminalScreen *screen);
@ -102,7 +103,7 @@ void terminal_screen_set_user_title (TerminalScreen *screen,
const char *text); const char *text);
void terminal_screen_set_override_title (TerminalScreen *screen, void terminal_screen_set_override_title (TerminalScreen *screen,
const char *title); const char *title);
const char *terminal_screen_get_dynamic_title (TerminalScreen *screen); const char *terminal_screen_get_dynamic_title (TerminalScreen *screen);
const char *terminal_screen_get_dynamic_icon_title (TerminalScreen *screen); const char *terminal_screen_get_dynamic_icon_title (TerminalScreen *screen);
@ -112,15 +113,15 @@ char *terminal_screen_get_current_dir_with_fallback (TerminalScreen *screen);
void terminal_screen_set_font (TerminalScreen *screen); void terminal_screen_set_font (TerminalScreen *screen);
void terminal_screen_set_font_scale (TerminalScreen *screen, void terminal_screen_set_font_scale (TerminalScreen *screen,
double factor); double factor);
double terminal_screen_get_font_scale (TerminalScreen *screen); double terminal_screen_get_font_scale (TerminalScreen *screen);
void terminal_screen_get_size (TerminalScreen *screen, void terminal_screen_get_size (TerminalScreen *screen,
int *width_chars, int *width_chars,
int *height_chars); int *height_chars);
void terminal_screen_get_cell_size (TerminalScreen *screen, void terminal_screen_get_cell_size (TerminalScreen *screen,
int *width_chars, int *width_chars,
int *height_chars); int *height_chars);
void _terminal_screen_update_scrollbar (TerminalScreen *screen); void _terminal_screen_update_scrollbar (TerminalScreen *screen);
@ -140,15 +141,16 @@ gboolean terminal_screen_has_foreground_process (TerminalScreen *screen);
#define TERMINAL_SCALE_MINIMUM (TERMINAL_SCALE_XXXXX_SMALL/1.2) #define TERMINAL_SCALE_MINIMUM (TERMINAL_SCALE_XXXXX_SMALL/1.2)
#define TERMINAL_SCALE_MAXIMUM (TERMINAL_SCALE_XXXXX_LARGE*1.2) #define TERMINAL_SCALE_MAXIMUM (TERMINAL_SCALE_XXXXX_LARGE*1.2)
struct _TerminalScreenPopupInfo { struct _TerminalScreenPopupInfo
int ref_count; {
TerminalWindow *window; int ref_count;
TerminalScreen *screen; TerminalWindow *window;
char *string; TerminalScreen *screen;
TerminalURLFlavour flavour; char *string;
guint button; TerminalURLFlavour flavour;
guint state; guint button;
guint32 timestamp; guint state;
guint32 timestamp;
}; };
TerminalScreenPopupInfo *terminal_screen_popup_info_ref (TerminalScreenPopupInfo *info); TerminalScreenPopupInfo *terminal_screen_popup_info_ref (TerminalScreenPopupInfo *info);

View File

@ -31,12 +31,12 @@
static GQuark static GQuark
get_quark (void) get_quark (void)
{ {
static GQuark quark = 0; static GQuark quark = 0;
if (G_UNLIKELY (!quark)) if (G_UNLIKELY (!quark))
quark = g_quark_from_static_string ("GT:data"); quark = g_quark_from_static_string ("GT:data");
return quark; return quark;
} }
@ -47,332 +47,340 @@ get_quark (void)
typedef struct _TerminalSearchDialogPrivate typedef struct _TerminalSearchDialogPrivate
{ {
GtkWidget *search_label; GtkWidget *search_label;
GtkWidget *search_entry; GtkWidget *search_entry;
GtkWidget *search_text_entry; GtkWidget *search_text_entry;
GtkWidget *match_case_checkbutton; GtkWidget *match_case_checkbutton;
GtkWidget *entire_word_checkbutton; GtkWidget *entire_word_checkbutton;
GtkWidget *regex_checkbutton; GtkWidget *regex_checkbutton;
GtkWidget *backwards_checkbutton; GtkWidget *backwards_checkbutton;
GtkWidget *wrap_around_checkbutton; GtkWidget *wrap_around_checkbutton;
GtkListStore *store; GtkListStore *store;
GtkEntryCompletion *completion; GtkEntryCompletion *completion;
/* Cached regex */ /* Cached regex */
GRegex *regex; GRegex *regex;
GRegexCompileFlags regex_compile_flags; GRegexCompileFlags regex_compile_flags;
} TerminalSearchDialogPrivate; } TerminalSearchDialogPrivate;
static void update_sensitivity (void *unused, static void update_sensitivity (void *unused,
GtkWidget *dialog); GtkWidget *dialog);
static void response_handler (GtkWidget *dialog, static void response_handler (GtkWidget *dialog,
gint response_id, gint response_id,
gpointer data); gpointer data);
static void terminal_search_dialog_private_destroy (TerminalSearchDialogPrivate *priv); static void terminal_search_dialog_private_destroy (TerminalSearchDialogPrivate *priv);
GtkWidget * GtkWidget *
terminal_search_dialog_new (GtkWindow *parent) terminal_search_dialog_new (GtkWindow *parent)
{ {
GtkWidget *dialog; GtkWidget *dialog;
TerminalSearchDialogPrivate *priv; TerminalSearchDialogPrivate *priv;
GtkListStore *store; GtkListStore *store;
GtkEntryCompletion *completion; GtkEntryCompletion *completion;
priv = g_new0 (TerminalSearchDialogPrivate, 1); priv = g_new0 (TerminalSearchDialogPrivate, 1);
if (!terminal_util_load_builder_file ("find-dialog.ui", if (!terminal_util_load_builder_file ("find-dialog.ui",
"find-dialog", &dialog, "find-dialog", &dialog,
"search-label", &priv->search_label, "search-label", &priv->search_label,
"search-entry", &priv->search_entry, "search-entry", &priv->search_entry,
"match-case-checkbutton", &priv->match_case_checkbutton, "match-case-checkbutton", &priv->match_case_checkbutton,
"entire-word-checkbutton", &priv->entire_word_checkbutton, "entire-word-checkbutton", &priv->entire_word_checkbutton,
"regex-checkbutton", &priv->regex_checkbutton, "regex-checkbutton", &priv->regex_checkbutton,
"search-backwards-checkbutton", &priv->backwards_checkbutton, "search-backwards-checkbutton", &priv->backwards_checkbutton,
"wrap-around-checkbutton", &priv->wrap_around_checkbutton, "wrap-around-checkbutton", &priv->wrap_around_checkbutton,
NULL)) NULL))
{ {
g_free (priv); g_free (priv);
return NULL; return NULL;
} }
g_object_set_qdata_full (G_OBJECT (dialog), get_quark (), priv, g_object_set_qdata_full (G_OBJECT (dialog), get_quark (), priv,
(GDestroyNotify) terminal_search_dialog_private_destroy); (GDestroyNotify) terminal_search_dialog_private_destroy);
priv->search_text_entry = gtk_bin_get_child (GTK_BIN (priv->search_entry)); priv->search_text_entry = gtk_bin_get_child (GTK_BIN (priv->search_entry));
gtk_widget_set_size_request (priv->search_entry, 300, -1); gtk_widget_set_size_request (priv->search_entry, 300, -1);
priv->store = store = gtk_list_store_new (1, G_TYPE_STRING); priv->store = store = gtk_list_store_new (1, G_TYPE_STRING);
g_object_set (G_OBJECT (priv->search_entry), g_object_set (G_OBJECT (priv->search_entry),
"model", store, "model", store,
"text-column", 0, "text-column", 0,
NULL); NULL);
priv->completion = completion = gtk_entry_completion_new (); priv->completion = completion = gtk_entry_completion_new ();
gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (store)); gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (store));
gtk_entry_completion_set_text_column (completion, 0); gtk_entry_completion_set_text_column (completion, 0);
gtk_entry_completion_set_minimum_key_length (completion, HISTORY_MIN_ITEM_LEN); gtk_entry_completion_set_minimum_key_length (completion, HISTORY_MIN_ITEM_LEN);
gtk_entry_completion_set_popup_completion (completion, FALSE); gtk_entry_completion_set_popup_completion (completion, FALSE);
gtk_entry_completion_set_inline_completion (completion, TRUE); gtk_entry_completion_set_inline_completion (completion, TRUE);
gtk_entry_set_completion (GTK_ENTRY (priv->search_text_entry), completion); gtk_entry_set_completion (GTK_ENTRY (priv->search_text_entry), completion);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, FALSE); gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, FALSE);
gtk_entry_set_activates_default (GTK_ENTRY (priv->search_text_entry), TRUE); gtk_entry_set_activates_default (GTK_ENTRY (priv->search_text_entry), TRUE);
g_signal_connect (priv->search_text_entry, "changed", G_CALLBACK (update_sensitivity), dialog); g_signal_connect (priv->search_text_entry, "changed", G_CALLBACK (update_sensitivity), dialog);
g_signal_connect (priv->regex_checkbutton, "toggled", G_CALLBACK (update_sensitivity), dialog); g_signal_connect (priv->regex_checkbutton, "toggled", G_CALLBACK (update_sensitivity), dialog);
g_signal_connect (dialog, "response", G_CALLBACK (response_handler), NULL); g_signal_connect (dialog, "response", G_CALLBACK (response_handler), NULL);
if (parent) if (parent)
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent); gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
return GTK_WIDGET (dialog); return GTK_WIDGET (dialog);
} }
void void
terminal_search_dialog_present (GtkWidget *dialog) terminal_search_dialog_present (GtkWidget *dialog)
{ {
TerminalSearchDialogPrivate *priv; TerminalSearchDialogPrivate *priv;
g_return_if_fail (GTK_IS_DIALOG (dialog)); g_return_if_fail (GTK_IS_DIALOG (dialog));
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog); priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
g_return_if_fail (priv); g_return_if_fail (priv);
gtk_window_present (GTK_WINDOW (dialog)); gtk_window_present (GTK_WINDOW (dialog));
gtk_widget_grab_focus (priv->search_text_entry); gtk_widget_grab_focus (priv->search_text_entry);
} }
static void static void
terminal_search_dialog_private_destroy (TerminalSearchDialogPrivate *priv) terminal_search_dialog_private_destroy (TerminalSearchDialogPrivate *priv)
{ {
if (priv->regex) if (priv->regex)
g_regex_unref (priv->regex); g_regex_unref (priv->regex);
g_object_unref (priv->store); g_object_unref (priv->store);
g_object_unref (priv->completion); g_object_unref (priv->completion);
g_free (priv); g_free (priv);
} }
static void static void
update_sensitivity (void *unused, GtkWidget *dialog) update_sensitivity (void *unused, GtkWidget *dialog)
{ {
TerminalSearchDialogPrivate *priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog); TerminalSearchDialogPrivate *priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
const gchar *search_string; const gchar *search_string;
gboolean valid; gboolean valid;
if (priv->regex) { if (priv->regex)
g_regex_unref (priv->regex); {
priv->regex = NULL; g_regex_unref (priv->regex);
} priv->regex = NULL;
}
search_string = gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry)); search_string = gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry));
g_return_if_fail (search_string != NULL); g_return_if_fail (search_string != NULL);
valid = *search_string != '\0'; valid = *search_string != '\0';
if (valid && GET_FLAG (regex_checkbutton)) { if (valid && GET_FLAG (regex_checkbutton))
/* Check that the regex is valid */ {
valid = NULL != terminal_search_dialog_get_regex (dialog); /* Check that the regex is valid */
/* TODO show the error message somewhere */ valid = NULL != terminal_search_dialog_get_regex (dialog);
} /* TODO show the error message somewhere */
}
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, valid); gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, valid);
} }
static gboolean static gboolean
remove_item (GtkListStore *store, remove_item (GtkListStore *store,
const gchar *text) const gchar *text)
{ {
GtkTreeIter iter; GtkTreeIter iter;
g_return_val_if_fail (text != NULL, FALSE); g_return_val_if_fail (text != NULL, FALSE);
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
return FALSE; return FALSE;
do { do
gchar *item_text; {
gchar *item_text;
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &item_text, -1); gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &item_text, -1);
if (item_text != NULL && strcmp (item_text, text) == 0) { if (item_text != NULL && strcmp (item_text, text) == 0)
gtk_list_store_remove (store, &iter); {
g_free (item_text); gtk_list_store_remove (store, &iter);
return TRUE; g_free (item_text);
} return TRUE;
}
g_free (item_text); g_free (item_text);
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)); }
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
return FALSE; return FALSE;
} }
static void static void
clamp_list_store (GtkListStore *store, clamp_list_store (GtkListStore *store,
guint max) guint max)
{ {
GtkTreePath *path; GtkTreePath *path;
GtkTreeIter iter; GtkTreeIter iter;
/* -1 because TreePath counts from 0 */ /* -1 because TreePath counts from 0 */
path = gtk_tree_path_new_from_indices (max - 1, -1); path = gtk_tree_path_new_from_indices (max - 1, -1);
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
while (1) while (1)
if (!gtk_list_store_remove (store, &iter)) if (!gtk_list_store_remove (store, &iter))
break; break;
gtk_tree_path_free (path); gtk_tree_path_free (path);
} }
static void static void
history_entry_insert (GtkListStore *store, history_entry_insert (GtkListStore *store,
const gchar *text) const gchar *text)
{ {
GtkTreeIter iter; GtkTreeIter iter;
g_return_if_fail (text != NULL); g_return_if_fail (text != NULL);
if (g_utf8_strlen (text, -1) <= HISTORY_MIN_ITEM_LEN) if (g_utf8_strlen (text, -1) <= HISTORY_MIN_ITEM_LEN)
return; return;
/* remove the text from the store if it was already /* remove the text from the store if it was already
* present. If it wasn't, clamp to max history - 1 * present. If it wasn't, clamp to max history - 1
* before inserting the new row, otherwise appending * before inserting the new row, otherwise appending
* would not work */ * would not work */
if (!remove_item (store, text)) if (!remove_item (store, text))
clamp_list_store (store, HISTORY_LENGTH - 1); clamp_list_store (store, HISTORY_LENGTH - 1);
gtk_list_store_insert (store, &iter, 0); gtk_list_store_insert (store, &iter, 0);
gtk_list_store_set (store, &iter, 0, text, -1); gtk_list_store_set (store, &iter, 0, text, -1);
} }
static void static void
response_handler (GtkWidget *dialog, response_handler (GtkWidget *dialog,
gint response_id, gint response_id,
gpointer data) gpointer data)
{ {
TerminalSearchDialogPrivate *priv; TerminalSearchDialogPrivate *priv;
const gchar *str; const gchar *str;
if (response_id != GTK_RESPONSE_ACCEPT) { if (response_id != GTK_RESPONSE_ACCEPT)
gtk_widget_hide (dialog); {
return; gtk_widget_hide (dialog);
} return;
}
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog); priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
str = gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry)); str = gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry));
if (*str != '\0') if (*str != '\0')
history_entry_insert (priv->store, str); history_entry_insert (priv->store, str);
} }
void void
terminal_search_dialog_set_search_text (GtkWidget *dialog, terminal_search_dialog_set_search_text (GtkWidget *dialog,
const gchar *text) const gchar *text)
{ {
TerminalSearchDialogPrivate *priv; TerminalSearchDialogPrivate *priv;
g_return_if_fail (GTK_IS_DIALOG (dialog)); g_return_if_fail (GTK_IS_DIALOG (dialog));
g_return_if_fail (text != NULL); g_return_if_fail (text != NULL);
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog); priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
g_return_if_fail (priv); g_return_if_fail (priv);
gtk_entry_set_text (GTK_ENTRY (priv->search_text_entry), text); gtk_entry_set_text (GTK_ENTRY (priv->search_text_entry), text);
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
GTK_RESPONSE_ACCEPT, GTK_RESPONSE_ACCEPT,
(*text != '\0')); (*text != '\0'));
} }
const gchar * const gchar *
terminal_search_dialog_get_search_text (GtkWidget *dialog) terminal_search_dialog_get_search_text (GtkWidget *dialog)
{ {
TerminalSearchDialogPrivate *priv; TerminalSearchDialogPrivate *priv;
g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL); g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog); priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
g_return_val_if_fail (priv, NULL); g_return_val_if_fail (priv, NULL);
return gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry)); return gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry));
} }
TerminalSearchFlags TerminalSearchFlags
terminal_search_dialog_get_search_flags (GtkWidget *dialog) terminal_search_dialog_get_search_flags (GtkWidget *dialog)
{ {
TerminalSearchDialogPrivate *priv; TerminalSearchDialogPrivate *priv;
TerminalSearchFlags flags = 0; TerminalSearchFlags flags = 0;
g_return_val_if_fail (GTK_IS_DIALOG (dialog), flags); g_return_val_if_fail (GTK_IS_DIALOG (dialog), flags);
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog); priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
g_return_val_if_fail (priv, flags); g_return_val_if_fail (priv, flags);
if (GET_FLAG (backwards_checkbutton)) if (GET_FLAG (backwards_checkbutton))
flags |= TERMINAL_SEARCH_FLAG_BACKWARDS; flags |= TERMINAL_SEARCH_FLAG_BACKWARDS;
if (GET_FLAG (wrap_around_checkbutton)) if (GET_FLAG (wrap_around_checkbutton))
flags |= TERMINAL_SEARCH_FLAG_WRAP_AROUND; flags |= TERMINAL_SEARCH_FLAG_WRAP_AROUND;
return flags; return flags;
} }
GRegex * GRegex *
terminal_search_dialog_get_regex (GtkWidget *dialog) terminal_search_dialog_get_regex (GtkWidget *dialog)
{ {
TerminalSearchDialogPrivate *priv; TerminalSearchDialogPrivate *priv;
GRegexCompileFlags compile_flags; GRegexCompileFlags compile_flags;
const char *text, *pattern; const char *text, *pattern;
g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL); g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog); priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
g_return_val_if_fail (priv, NULL); g_return_val_if_fail (priv, NULL);
pattern = text = terminal_search_dialog_get_search_text (dialog); pattern = text = terminal_search_dialog_get_search_text (dialog);
compile_flags = G_REGEX_OPTIMIZE; compile_flags = G_REGEX_OPTIMIZE;
if (!GET_FLAG (match_case_checkbutton)) if (!GET_FLAG (match_case_checkbutton))
compile_flags |= G_REGEX_CASELESS; compile_flags |= G_REGEX_CASELESS;
if (GET_FLAG (regex_checkbutton)) if (GET_FLAG (regex_checkbutton))
compile_flags |= G_REGEX_MULTILINE; compile_flags |= G_REGEX_MULTILINE;
else else
pattern = g_regex_escape_string (text, -1); pattern = g_regex_escape_string (text, -1);
if (GET_FLAG (entire_word_checkbutton)) { if (GET_FLAG (entire_word_checkbutton))
const char *old_pattern = pattern; {
pattern = g_strdup_printf ("\\b%s\\b", pattern); const char *old_pattern = pattern;
if (old_pattern != text) pattern = g_strdup_printf ("\\b%s\\b", pattern);
g_free ((char *) old_pattern); if (old_pattern != text)
} g_free ((char *) old_pattern);
}
if (!priv->regex || priv->regex_compile_flags != compile_flags) { if (!priv->regex || priv->regex_compile_flags != compile_flags)
priv->regex_compile_flags = compile_flags; {
if (priv->regex) priv->regex_compile_flags = compile_flags;
g_regex_unref (priv->regex); if (priv->regex)
g_regex_unref (priv->regex);
/* TODO Error handling */ /* TODO Error handling */
priv->regex = g_regex_new (pattern, compile_flags, 0, NULL); priv->regex = g_regex_new (pattern, compile_flags, 0, NULL);
} }
if (pattern != text) if (pattern != text)
g_free ((char *) pattern); g_free ((char *) pattern);
return priv->regex; return priv->regex;
} }

View File

@ -25,9 +25,10 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum _TerminalSearchFlags { typedef enum _TerminalSearchFlags
TERMINAL_SEARCH_FLAG_BACKWARDS = 1 << 0, {
TERMINAL_SEARCH_FLAG_WRAP_AROUND = 1 << 1 TERMINAL_SEARCH_FLAG_BACKWARDS = 1 << 0,
TERMINAL_SEARCH_FLAG_WRAP_AROUND = 1 << 1
} TerminalSearchFlags; } TerminalSearchFlags;
@ -36,12 +37,12 @@ GtkWidget *terminal_search_dialog_new (GtkWindow *parent);
void terminal_search_dialog_present (GtkWidget *dialog); void terminal_search_dialog_present (GtkWidget *dialog);
void terminal_search_dialog_set_search_text (GtkWidget *dialog, void terminal_search_dialog_set_search_text (GtkWidget *dialog,
const gchar *text); const gchar *text);
const gchar *terminal_search_dialog_get_search_text (GtkWidget *dialog); const gchar *terminal_search_dialog_get_search_text (GtkWidget *dialog);
TerminalSearchFlags TerminalSearchFlags
terminal_search_dialog_get_search_flags(GtkWidget *dialog); terminal_search_dialog_get_search_flags(GtkWidget *dialog);
GRegex *terminal_search_dialog_get_regex (GtkWidget *dialog); GRegex *terminal_search_dialog_get_regex (GtkWidget *dialog);
G_END_DECLS G_END_DECLS

View File

@ -30,22 +30,22 @@
struct _TerminalTabLabelPrivate struct _TerminalTabLabelPrivate
{ {
TerminalScreen *screen; TerminalScreen *screen;
GtkWidget *label; GtkWidget *label;
GtkWidget *close_button; GtkWidget *close_button;
gboolean bold; gboolean bold;
}; };
enum enum
{ {
PROP_0, PROP_0,
PROP_SCREEN PROP_SCREEN
}; };
enum enum
{ {
CLOSE_BUTTON_CLICKED, CLOSE_BUTTON_CLICKED,
LAST_SIGNAL LAST_SIGNAL
}; };
static guint signals[LAST_SIGNAL]; static guint signals[LAST_SIGNAL];
@ -58,7 +58,7 @@ static void
close_button_clicked_cb (GtkWidget *widget, close_button_clicked_cb (GtkWidget *widget,
TerminalTabLabel *tab_label) TerminalTabLabel *tab_label)
{ {
g_signal_emit (tab_label, signals[CLOSE_BUTTON_CLICKED], 0); g_signal_emit (tab_label, signals[CLOSE_BUTTON_CLICKED], 0);
} }
static void static void
@ -66,15 +66,15 @@ sync_tab_label (TerminalScreen *screen,
GParamSpec *pspec, GParamSpec *pspec,
GtkWidget *label) GtkWidget *label)
{ {
GtkWidget *hbox; GtkWidget *hbox;
const char *title; const char *title;
title = terminal_screen_get_title (screen); title = terminal_screen_get_title (screen);
hbox = gtk_widget_get_parent (label); hbox = gtk_widget_get_parent (label);
gtk_label_set_text (GTK_LABEL (label), title); gtk_label_set_text (GTK_LABEL (label), title);
gtk_widget_set_tooltip_text (hbox, title); gtk_widget_set_tooltip_text (hbox, title);
} }
/* public functions */ /* public functions */
@ -85,33 +85,33 @@ static void
terminal_tab_label_parent_set (GtkWidget *widget, terminal_tab_label_parent_set (GtkWidget *widget,
GtkWidget *old_parent) GtkWidget *old_parent)
{ {
void (* parent_set) (GtkWidget *, GtkWidget *) = GTK_WIDGET_CLASS (terminal_tab_label_parent_class)->parent_set; void (* parent_set) (GtkWidget *, GtkWidget *) = GTK_WIDGET_CLASS (terminal_tab_label_parent_class)->parent_set;
if (parent_set) if (parent_set)
parent_set (widget, old_parent); parent_set (widget, old_parent);
} }
static void static void
terminal_tab_label_style_set (GtkWidget *widget, terminal_tab_label_style_set (GtkWidget *widget,
GtkStyle *previous_style) GtkStyle *previous_style)
{ {
TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (widget); TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (widget);
TerminalTabLabelPrivate *priv = tab_label->priv; TerminalTabLabelPrivate *priv = tab_label->priv;
void (* style_set) (GtkWidget *, GtkStyle *) = GTK_WIDGET_CLASS (terminal_tab_label_parent_class)->style_set; void (* style_set) (GtkWidget *, GtkStyle *) = GTK_WIDGET_CLASS (terminal_tab_label_parent_class)->style_set;
int h, w; int h, w;
if (style_set) if (style_set)
style_set (widget, previous_style); style_set (widget, previous_style);
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget), gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
GTK_ICON_SIZE_MENU, &w, &h); GTK_ICON_SIZE_MENU, &w, &h);
gtk_widget_set_size_request (priv->close_button, w + 2, h + 2); gtk_widget_set_size_request (priv->close_button, w + 2, h + 2);
} }
static void static void
terminal_tab_label_init (TerminalTabLabel *tab_label) terminal_tab_label_init (TerminalTabLabel *tab_label)
{ {
tab_label->priv = TERMINAL_TAB_LABEL_GET_PRIVATE (tab_label); tab_label->priv = TERMINAL_TAB_LABEL_GET_PRIVATE (tab_label);
} }
static GObject * static GObject *
@ -119,51 +119,51 @@ terminal_tab_label_constructor (GType type,
guint n_construct_properties, guint n_construct_properties,
GObjectConstructParam *construct_params) GObjectConstructParam *construct_params)
{ {
GObject *object; GObject *object;
TerminalTabLabel *tab_label; TerminalTabLabel *tab_label;
TerminalTabLabelPrivate *priv; TerminalTabLabelPrivate *priv;
GtkWidget *hbox, *label, *close_button, *image; GtkWidget *hbox, *label, *close_button, *image;
object = G_OBJECT_CLASS (terminal_tab_label_parent_class)->constructor object = G_OBJECT_CLASS (terminal_tab_label_parent_class)->constructor
(type, n_construct_properties, construct_params); (type, n_construct_properties, construct_params);
tab_label = TERMINAL_TAB_LABEL (object); tab_label = TERMINAL_TAB_LABEL (object);
hbox = GTK_WIDGET (tab_label); hbox = GTK_WIDGET (tab_label);
priv = tab_label->priv; priv = tab_label->priv;
g_assert (priv->screen != NULL); g_assert (priv->screen != NULL);
gtk_box_set_spacing (GTK_BOX (hbox), SPACING);
priv->label = label = gtk_label_new (NULL); gtk_box_set_spacing (GTK_BOX (hbox), SPACING);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_misc_set_padding (GTK_MISC (label), 0, 0);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); priv->label = label = gtk_label_new (NULL);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_misc_set_padding (GTK_MISC (label), 0, 0);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
priv->close_button = close_button = gtk_button_new (); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
gtk_widget_set_name (close_button, "mate-terminal-tab-close-button");
gtk_widget_set_tooltip_text (close_button, _("Close tab"));
image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); priv->close_button = close_button = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (close_button), image); gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0); gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
gtk_widget_set_name (close_button, "mate-terminal-tab-close-button");
gtk_widget_set_tooltip_text (close_button, _("Close tab"));
sync_tab_label (priv->screen, NULL, label); image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
g_signal_connect (priv->screen, "notify::title", gtk_container_add (GTK_CONTAINER (close_button), image);
G_CALLBACK (sync_tab_label), label); gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
g_signal_connect (close_button, "clicked", sync_tab_label (priv->screen, NULL, label);
G_CALLBACK (close_button_clicked_cb), tab_label); g_signal_connect (priv->screen, "notify::title",
G_CALLBACK (sync_tab_label), label);
gtk_widget_show_all (hbox); g_signal_connect (close_button, "clicked",
G_CALLBACK (close_button_clicked_cb), tab_label);
return object; gtk_widget_show_all (hbox);
return object;
} }
static void static void
@ -171,7 +171,7 @@ terminal_tab_label_finalize (GObject *object)
{ {
// TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object); // TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object);
G_OBJECT_CLASS (terminal_tab_label_parent_class)->finalize (object); G_OBJECT_CLASS (terminal_tab_label_parent_class)->finalize (object);
} }
static void static void
@ -180,51 +180,52 @@ terminal_tab_label_set_property (GObject *object,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object); TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object);
TerminalTabLabelPrivate *priv = tab_label->priv; TerminalTabLabelPrivate *priv = tab_label->priv;
switch (prop_id) { switch (prop_id)
case PROP_SCREEN: {
priv->screen = g_value_get_object (value); case PROP_SCREEN:
break; priv->screen = g_value_get_object (value);
default: break;
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); default:
break; G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} break;
}
} }
static void static void
terminal_tab_label_class_init (TerminalTabLabelClass *klass) terminal_tab_label_class_init (TerminalTabLabelClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gobject_class->constructor = terminal_tab_label_constructor; gobject_class->constructor = terminal_tab_label_constructor;
gobject_class->finalize = terminal_tab_label_finalize; gobject_class->finalize = terminal_tab_label_finalize;
gobject_class->set_property = terminal_tab_label_set_property; gobject_class->set_property = terminal_tab_label_set_property;
widget_class->parent_set = terminal_tab_label_parent_set; widget_class->parent_set = terminal_tab_label_parent_set;
widget_class->style_set = terminal_tab_label_style_set; widget_class->style_set = terminal_tab_label_style_set;
signals[CLOSE_BUTTON_CLICKED] = signals[CLOSE_BUTTON_CLICKED] =
g_signal_new (I_("close-button-clicked"), g_signal_new (I_("close-button-clicked"),
G_OBJECT_CLASS_TYPE (gobject_class), G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (TerminalTabLabelClass, close_button_clicked), G_STRUCT_OFFSET (TerminalTabLabelClass, close_button_clicked),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__VOID, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, G_TYPE_NONE,
0); 0);
g_object_class_install_property g_object_class_install_property
(gobject_class, (gobject_class,
PROP_SCREEN, PROP_SCREEN,
g_param_spec_object ("screen", NULL, NULL, g_param_spec_object ("screen", NULL, NULL,
TERMINAL_TYPE_SCREEN, TERMINAL_TYPE_SCREEN,
G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
G_PARAM_CONSTRUCT_ONLY)); G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (gobject_class, sizeof (TerminalTabLabelPrivate)); g_type_class_add_private (gobject_class, sizeof (TerminalTabLabelPrivate));
} }
/* public API */ /* public API */
@ -238,9 +239,9 @@ terminal_tab_label_class_init (TerminalTabLabelClass *klass)
GtkWidget * GtkWidget *
terminal_tab_label_new (TerminalScreen *screen) terminal_tab_label_new (TerminalScreen *screen)
{ {
return g_object_new (TERMINAL_TYPE_TAB_LABEL, return g_object_new (TERMINAL_TYPE_TAB_LABEL,
"screen", screen, "screen", screen,
NULL); NULL);
} }
/** /**
@ -254,36 +255,37 @@ void
terminal_tab_label_set_bold (TerminalTabLabel *tab_label, terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
gboolean bold) gboolean bold)
{ {
TerminalTabLabelPrivate *priv = tab_label->priv; TerminalTabLabelPrivate *priv = tab_label->priv;
PangoAttrList *attr_list; PangoAttrList *attr_list;
PangoAttribute *weight_attr; PangoAttribute *weight_attr;
gboolean free_list = FALSE; gboolean free_list = FALSE;
bold = bold != FALSE; bold = bold != FALSE;
if (priv->bold == bold) if (priv->bold == bold)
return; return;
priv->bold = bold; priv->bold = bold;
attr_list = gtk_label_get_attributes (GTK_LABEL (priv->label)); attr_list = gtk_label_get_attributes (GTK_LABEL (priv->label));
if (!attr_list) { if (!attr_list)
attr_list = pango_attr_list_new (); {
free_list = TRUE; attr_list = pango_attr_list_new ();
} free_list = TRUE;
}
if (bold) if (bold)
weight_attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); weight_attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
else else
weight_attr = pango_attr_weight_new (PANGO_WEIGHT_NORMAL); weight_attr = pango_attr_weight_new (PANGO_WEIGHT_NORMAL);
/* gtk_label_get_attributes() returns the label's internal list, /* gtk_label_get_attributes() returns the label's internal list,
* which we're probably not supposed to modify directly. * which we're probably not supposed to modify directly.
* It seems to work ok however. * It seems to work ok however.
*/ */
pango_attr_list_change (attr_list, weight_attr); pango_attr_list_change (attr_list, weight_attr);
gtk_label_set_attributes (GTK_LABEL (priv->label), attr_list); gtk_label_set_attributes (GTK_LABEL (priv->label), attr_list);
if (free_list) if (free_list)
pango_attr_list_unref (attr_list); pango_attr_list_unref (attr_list);
} }

View File

@ -38,18 +38,18 @@ typedef struct _TerminalTabLabelPrivate TerminalTabLabelPrivate;
struct _TerminalTabLabel struct _TerminalTabLabel
{ {
GtkHBox parent_instance; GtkHBox parent_instance;
/*< private >*/ /*< private >*/
TerminalTabLabelPrivate *priv; TerminalTabLabelPrivate *priv;
}; };
struct _TerminalTabLabelClass struct _TerminalTabLabelClass
{ {
GtkHBoxClass parent_class; GtkHBoxClass parent_class;
/* Signals */ /* Signals */
void (* close_button_clicked) (TerminalTabLabel *tab_label); void (* close_button_clicked) (TerminalTabLabel *tab_label);
}; };
GType terminal_tab_label_get_type (void); GType terminal_tab_label_get_type (void);
@ -57,7 +57,7 @@ GType terminal_tab_label_get_type (void);
GtkWidget *terminal_tab_label_new (TerminalScreen *screen); GtkWidget *terminal_tab_label_new (TerminalScreen *screen);
void terminal_tab_label_set_bold (TerminalTabLabel *tab_label, void terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
gboolean bold); gboolean bold);
G_END_DECLS G_END_DECLS

View File

@ -56,8 +56,8 @@ struct _TerminalTabsMenuPrivate
enum enum
{ {
PROP_0, PROP_0,
PROP_WINDOW PROP_WINDOW
}; };
static void terminal_tabs_menu_update (TerminalTabsMenu *menu); static void terminal_tabs_menu_update (TerminalTabsMenu *menu);
@ -76,77 +76,77 @@ G_DEFINE_TYPE (TerminalTabsMenu, terminal_tabs_menu, G_TYPE_OBJECT)
static guint static guint
allocate_tab_id (void) allocate_tab_id (void)
{ {
int bit; int bit;
guint b, len; guint b, len;
guint8 *data; guint8 *data;
guint8 byte, mask; guint8 byte, mask;
if (n_tabs++ == 0) if (n_tabs++ == 0)
{ {
g_assert (tabs_id_array == NULL); g_assert (tabs_id_array == NULL);
tabs_id_array = g_byte_array_sized_new (16); tabs_id_array = g_byte_array_sized_new (16);
} }
/* Find a free ID */ /* Find a free ID */
len = tabs_id_array->len; len = tabs_id_array->len;
data = tabs_id_array->data; data = tabs_id_array->data;
for (b = 0; b < len; ++b) for (b = 0; b < len; ++b)
{ {
if (data[b] != 0xff) if (data[b] != 0xff)
break; break;
} }
/* Need to append a new byte */ /* Need to append a new byte */
if (b == len) if (b == len)
{ {
guint8 bytes[] = { 0 }; guint8 bytes[] = { 0 };
g_byte_array_append (tabs_id_array, bytes, G_N_ELEMENTS (bytes)); g_byte_array_append (tabs_id_array, bytes, G_N_ELEMENTS (bytes));
g_assert (tabs_id_array->len > b); g_assert (tabs_id_array->len > b);
} }
data = tabs_id_array->data + b; data = tabs_id_array->data + b;
byte = 0xff ^ *data; byte = 0xff ^ *data;
/* Now find the first free bit */ /* Now find the first free bit */
bit = g_bit_nth_lsf (byte, -1); bit = g_bit_nth_lsf (byte, -1);
mask = 1 << bit; mask = 1 << bit;
g_assert (bit >= 0 && bit <= 7); g_assert (bit >= 0 && bit <= 7);
g_assert ((*data & mask) == 0); g_assert ((*data & mask) == 0);
/* And mark it as allocated */ /* And mark it as allocated */
*data |= mask; *data |= mask;
return b * 8 + bit; return b * 8 + bit;
} }
static void static void
free_tab_id (GtkAction *action) free_tab_id (GtkAction *action)
{ {
const char *name; const char *name;
guint id; guint id;
guint8 *data; guint8 *data;
guint b, bit; guint b, bit;
name = gtk_action_get_name (action); name = gtk_action_get_name (action);
id = g_ascii_strtoull (name + ACTION_VERB_FORMAT_PREFIX_LEN, NULL, id = g_ascii_strtoull (name + ACTION_VERB_FORMAT_PREFIX_LEN, NULL,
ACTION_VERB_FORMAT_BASE); ACTION_VERB_FORMAT_BASE);
g_assert (id < tabs_id_array->len * 8); g_assert (id < tabs_id_array->len * 8);
b = id >> 3; b = id >> 3;
bit = id & 0x7; bit = id & 0x7;
data = tabs_id_array->data + b; data = tabs_id_array->data + b;
*data &= ~(1 << bit); *data &= ~(1 << bit);
g_assert (n_tabs > 0); g_assert (n_tabs > 0);
if (--n_tabs == 0) if (--n_tabs == 0)
{ {
g_assert (tabs_id_array != NULL); g_assert (tabs_id_array != NULL);
g_byte_array_free (tabs_id_array, TRUE); g_byte_array_free (tabs_id_array, TRUE);
tabs_id_array = NULL; tabs_id_array = NULL;
} }
} }
static void static void
tab_action_activate_cb (GtkToggleAction *action, tab_action_activate_cb (GtkToggleAction *action,
TerminalTabsMenu *menu) TerminalTabsMenu *menu)
{ {
TerminalTabsMenuPrivate *priv = menu->priv; TerminalTabsMenuPrivate *priv = menu->priv;
TerminalScreen *screen; TerminalScreen *screen;
@ -161,14 +161,14 @@ tab_action_activate_cb (GtkToggleAction *action,
if (terminal_window_get_active (priv->window) != screen) if (terminal_window_get_active (priv->window) != screen)
{ {
terminal_window_switch_screen (priv->window, screen); terminal_window_switch_screen (priv->window, screen);
} }
} }
static void static void
sync_tab_title (TerminalScreen *screen, sync_tab_title (TerminalScreen *screen,
GParamSpec *pspec, GParamSpec *pspec,
GtkAction *action) GtkAction *action)
{ {
const char *title; const char *title;
@ -180,28 +180,28 @@ sync_tab_title (TerminalScreen *screen,
static void static void
notebook_page_added_cb (GtkNotebook *notebook, notebook_page_added_cb (GtkNotebook *notebook,
TerminalScreenContainer *container, TerminalScreenContainer *container,
guint position, guint position,
TerminalTabsMenu *menu) TerminalTabsMenu *menu)
{ {
TerminalTabsMenuPrivate *priv = menu->priv; TerminalTabsMenuPrivate *priv = menu->priv;
GtkAction *action; GtkAction *action;
char verb[ACTION_VERB_FORMAT_LENGTH]; char verb[ACTION_VERB_FORMAT_LENGTH];
GSList *group; GSList *group;
TerminalScreen *screen; TerminalScreen *screen;
screen = terminal_screen_container_get_screen (container); screen = terminal_screen_container_get_screen (container);
g_snprintf (verb, sizeof (verb), ACTION_VERB_FORMAT, allocate_tab_id ()); g_snprintf (verb, sizeof (verb), ACTION_VERB_FORMAT, allocate_tab_id ());
action = g_object_new (GTK_TYPE_RADIO_ACTION, action = g_object_new (GTK_TYPE_RADIO_ACTION,
"name", verb, "name", verb,
"tooltip", _("Switch to this tab"), "tooltip", _("Switch to this tab"),
NULL); NULL);
sync_tab_title (screen, NULL, action); sync_tab_title (screen, NULL, action);
/* make sure the action is alive when handling the signal, see bug #169833 */ /* make sure the action is alive when handling the signal, see bug #169833 */
g_signal_connect_object (screen, "notify::title", g_signal_connect_object (screen, "notify::title",
G_CALLBACK (sync_tab_title), action, 0); G_CALLBACK (sync_tab_title), action, 0);
gtk_action_group_add_action_with_accel (priv->action_group, action, NULL); gtk_action_group_add_action_with_accel (priv->action_group, action, NULL);
@ -218,7 +218,7 @@ notebook_page_added_cb (GtkNotebook *notebook,
g_object_set_data (G_OBJECT (action), DATA_KEY, screen); g_object_set_data (G_OBJECT (action), DATA_KEY, screen);
g_signal_connect (action, "activate", g_signal_connect (action, "activate",
G_CALLBACK (tab_action_activate_cb), menu); G_CALLBACK (tab_action_activate_cb), menu);
g_object_unref (action); g_object_unref (action);
@ -228,37 +228,37 @@ notebook_page_added_cb (GtkNotebook *notebook,
static void static void
notebook_page_removed_cb (GtkNotebook *notebook, notebook_page_removed_cb (GtkNotebook *notebook,
TerminalScreenContainer *container, TerminalScreenContainer *container,
guint position, guint position,
TerminalTabsMenu *menu) TerminalTabsMenu *menu)
{ {
TerminalTabsMenuPrivate *priv = menu->priv; TerminalTabsMenuPrivate *priv = menu->priv;
GtkAction *action; GtkAction *action;
TerminalScreen *screen; TerminalScreen *screen;
screen = terminal_screen_container_get_screen (container); screen = terminal_screen_container_get_screen (container);
action = g_object_get_data (G_OBJECT (screen), DATA_KEY); action = g_object_get_data (G_OBJECT (screen), DATA_KEY);
g_return_if_fail (action != NULL); g_return_if_fail (action != NULL);
free_tab_id (action); free_tab_id (action);
g_signal_handlers_disconnect_by_func g_signal_handlers_disconnect_by_func
(screen, G_CALLBACK (sync_tab_title), action); (screen, G_CALLBACK (sync_tab_title), action);
g_signal_handlers_disconnect_by_func g_signal_handlers_disconnect_by_func
(action, G_CALLBACK (tab_action_activate_cb), menu); (action, G_CALLBACK (tab_action_activate_cb), menu);
g_object_set_data (G_OBJECT (screen), DATA_KEY, NULL); g_object_set_data (G_OBJECT (screen), DATA_KEY, NULL);
gtk_action_group_remove_action (priv->action_group, action); gtk_action_group_remove_action (priv->action_group, action);
terminal_tabs_menu_update (menu); terminal_tabs_menu_update (menu);
} }
static void static void
notebook_page_reordered_cb (GtkNotebook *notebook, notebook_page_reordered_cb (GtkNotebook *notebook,
GtkBin *bin, GtkBin *bin,
guint position, guint position,
TerminalTabsMenu *menu) TerminalTabsMenu *menu)
{ {
terminal_tabs_menu_update (menu); terminal_tabs_menu_update (menu);
} }
@ -273,28 +273,28 @@ notebook_page_switch_cb (GtkNotebook *notebook,
guint position, guint position,
TerminalTabsMenu *menu) TerminalTabsMenu *menu)
{ {
TerminalScreenContainer *container; TerminalScreenContainer *container;
TerminalScreen *screen; TerminalScreen *screen;
GtkAction *action; GtkAction *action;
#if GTK_CHECK_VERSION (2, 90, 6) #if GTK_CHECK_VERSION (2, 90, 6)
container = TERMINAL_SCREEN_CONTAINER (page); container = TERMINAL_SCREEN_CONTAINER (page);
#else #else
container = TERMINAL_SCREEN_CONTAINER (gtk_notebook_get_nth_page (notebook, position)); container = TERMINAL_SCREEN_CONTAINER (gtk_notebook_get_nth_page (notebook, position));
#endif #endif
screen = terminal_screen_container_get_screen (container); screen = terminal_screen_container_get_screen (container);
action = g_object_get_data (G_OBJECT (screen), DATA_KEY); action = g_object_get_data (G_OBJECT (screen), DATA_KEY);
g_signal_handlers_block_by_func (action, G_CALLBACK (tab_action_activate_cb), menu); g_signal_handlers_block_by_func (action, G_CALLBACK (tab_action_activate_cb), menu);
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
g_signal_handlers_unblock_by_func (action, G_CALLBACK (tab_action_activate_cb), menu); g_signal_handlers_unblock_by_func (action, G_CALLBACK (tab_action_activate_cb), menu);
} }
static void static void
connect_proxy_cb (GtkActionGroup *action_group, connect_proxy_cb (GtkActionGroup *action_group,
GtkAction *action, GtkAction *action,
GtkWidget *proxy, GtkWidget *proxy,
gpointer dummy) gpointer dummy)
{ {
if (GTK_IS_MENU_ITEM (proxy)) if (GTK_IS_MENU_ITEM (proxy))
{ {
@ -310,7 +310,7 @@ connect_proxy_cb (GtkActionGroup *action_group,
static void static void
terminal_tabs_menu_set_window (TerminalTabsMenu *menu, terminal_tabs_menu_set_window (TerminalTabsMenu *menu,
TerminalWindow *window) TerminalWindow *window)
{ {
TerminalTabsMenuPrivate *priv = menu->priv; TerminalTabsMenuPrivate *priv = menu->priv;
GtkWidget *notebook; GtkWidget *notebook;
@ -324,49 +324,49 @@ terminal_tabs_menu_set_window (TerminalTabsMenu *menu,
g_object_unref (priv->action_group); g_object_unref (priv->action_group);
priv->anchor_action = g_object_new (GTK_TYPE_RADIO_ACTION, priv->anchor_action = g_object_new (GTK_TYPE_RADIO_ACTION,
"name", "TabsMenuAnchorAction", "name", "TabsMenuAnchorAction",
NULL); NULL);
gtk_action_group_add_action (priv->action_group, priv->anchor_action); gtk_action_group_add_action (priv->action_group, priv->anchor_action);
g_object_unref (priv->anchor_action); g_object_unref (priv->anchor_action);
g_signal_connect (priv->action_group, "connect-proxy", g_signal_connect (priv->action_group, "connect-proxy",
G_CALLBACK (connect_proxy_cb), NULL); G_CALLBACK (connect_proxy_cb), NULL);
notebook = terminal_window_get_notebook (window); notebook = terminal_window_get_notebook (window);
g_signal_connect_object (notebook, "page-added", g_signal_connect_object (notebook, "page-added",
G_CALLBACK (notebook_page_added_cb), menu, 0); G_CALLBACK (notebook_page_added_cb), menu, 0);
g_signal_connect_object (notebook, "page-removed", g_signal_connect_object (notebook, "page-removed",
G_CALLBACK (notebook_page_removed_cb), menu, 0); G_CALLBACK (notebook_page_removed_cb), menu, 0);
g_signal_connect_object (notebook, "page-reordered", g_signal_connect_object (notebook, "page-reordered",
G_CALLBACK (notebook_page_reordered_cb), menu, 0); G_CALLBACK (notebook_page_reordered_cb), menu, 0);
g_signal_connect_object (notebook, "switch-page", g_signal_connect_object (notebook, "switch-page",
G_CALLBACK (notebook_page_switch_cb), menu, 0); G_CALLBACK (notebook_page_switch_cb), menu, 0);
} }
static void static void
terminal_tabs_menu_set_property (GObject *object, terminal_tabs_menu_set_property (GObject *object,
guint prop_id, guint prop_id,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
TerminalTabsMenu *menu = TERMINAL_TABS_MENU (object); TerminalTabsMenu *menu = TERMINAL_TABS_MENU (object);
switch (prop_id) switch (prop_id)
{ {
case PROP_WINDOW: case PROP_WINDOW:
terminal_tabs_menu_set_window (menu, g_value_get_object (value)); terminal_tabs_menu_set_window (menu, g_value_get_object (value));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
} }
} }
static void static void
terminal_tabs_menu_get_property (GObject *object, terminal_tabs_menu_get_property (GObject *object,
guint prop_id, guint prop_id,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
/* no readable properties */ /* no readable properties */
g_return_if_reached (); g_return_if_reached ();
@ -381,16 +381,16 @@ terminal_tabs_menu_class_init (TerminalTabsMenuClass *klass)
object_class->get_property = terminal_tabs_menu_get_property; object_class->get_property = terminal_tabs_menu_get_property;
g_object_class_install_property (object_class, g_object_class_install_property (object_class,
PROP_WINDOW, PROP_WINDOW,
g_param_spec_object ("window", NULL, NULL, g_param_spec_object ("window", NULL, NULL,
TERMINAL_TYPE_WINDOW, TERMINAL_TYPE_WINDOW,
G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
G_PARAM_CONSTRUCT_ONLY)); G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (object_class, sizeof (TerminalTabsMenuPrivate)); g_type_class_add_private (object_class, sizeof (TerminalTabsMenuPrivate));
/* We don't want to save accels, so skip them */ /* We don't want to save accels, so skip them */
gtk_accel_map_add_filter ("<Actions>/Main/TabsSwitch*"); gtk_accel_map_add_filter ("<Actions>/Main/TabsSwitch*");
} }
static void static void
@ -417,29 +417,29 @@ TerminalTabsMenu *
terminal_tabs_menu_new (TerminalWindow *window) terminal_tabs_menu_new (TerminalWindow *window)
{ {
return TERMINAL_TABS_MENU (g_object_new (TERMINAL_TYPE_TABS_MENU, return TERMINAL_TABS_MENU (g_object_new (TERMINAL_TYPE_TABS_MENU,
"window", window, "window", window,
NULL)); NULL));
} }
static void static void
tab_set_action_accelerator (GtkActionGroup *action_group, tab_set_action_accelerator (GtkActionGroup *action_group,
GtkAction *action, GtkAction *action,
guint tab_number, guint tab_number,
gboolean is_single_tab) gboolean is_single_tab)
{ {
if (!is_single_tab && if (!is_single_tab &&
tab_number < TERMINAL_ACCELS_N_TABS_SWITCH) tab_number < TERMINAL_ACCELS_N_TABS_SWITCH)
{ {
char accel_path[ACCEL_PATH_FORMAT_LENGTH]; char accel_path[ACCEL_PATH_FORMAT_LENGTH];
g_snprintf (accel_path, sizeof (accel_path), ACCEL_PATH_FORMAT, tab_number + 1); g_snprintf (accel_path, sizeof (accel_path), ACCEL_PATH_FORMAT, tab_number + 1);
gtk_action_set_accel_path (action, accel_path); gtk_action_set_accel_path (action, accel_path);
} }
else else
{ {
gtk_action_set_accel_path (action, NULL); gtk_action_set_accel_path (action, NULL);
return; return;
} }
} }
static void static void
@ -467,20 +467,20 @@ terminal_tabs_menu_update (TerminalTabsMenu *menu)
for (l = tabs; l != NULL; l = l->next) for (l = tabs; l != NULL; l = l->next)
{ {
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (l->data); TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (l->data);
GObject *screen = G_OBJECT (terminal_screen_container_get_screen (container)); GObject *screen = G_OBJECT (terminal_screen_container_get_screen (container));
action = g_object_get_data (screen, DATA_KEY); action = g_object_get_data (screen, DATA_KEY);
g_return_if_fail (action != NULL); g_return_if_fail (action != NULL);
verb = gtk_action_get_name (action); verb = gtk_action_get_name (action);
tab_set_action_accelerator (p->action_group, action, i++, is_single_tab); tab_set_action_accelerator (p->action_group, action, i++, is_single_tab);
gtk_ui_manager_add_ui (manager, p->ui_id, gtk_ui_manager_add_ui (manager, p->ui_id,
UI_PATH, UI_PATH,
verb, verb, verb, verb,
GTK_UI_MANAGER_MENUITEM, FALSE); GTK_UI_MANAGER_MENUITEM, FALSE);
} }
g_list_free (tabs); g_list_free (tabs);

File diff suppressed because it is too large Load Diff

View File

@ -33,18 +33,18 @@ G_BEGIN_DECLS
void terminal_util_set_unique_role (GtkWindow *window, const char *prefix); void terminal_util_set_unique_role (GtkWindow *window, const char *prefix);
void terminal_util_show_error_dialog (GtkWindow *transient_parent, void terminal_util_show_error_dialog (GtkWindow *transient_parent,
GtkWidget **weap_ptr, GtkWidget **weap_ptr,
GError *error, GError *error,
const char *message_format, ...) G_GNUC_PRINTF(4, 5); const char *message_format, ...) G_GNUC_PRINTF(4, 5);
void terminal_util_show_help (const char *topic, GtkWindow *transient_parent); void terminal_util_show_help (const char *topic, GtkWindow *transient_parent);
void terminal_util_set_labelled_by (GtkWidget *widget, void terminal_util_set_labelled_by (GtkWidget *widget,
GtkLabel *label); GtkLabel *label);
void terminal_util_set_atk_name_description (GtkWidget *widget, void terminal_util_set_atk_name_description (GtkWidget *widget,
const char *name, const char *name,
const char *desc); const char *desc);
void terminal_util_open_url (GtkWidget *parent, void terminal_util_open_url (GtkWidget *parent,
const char *orig_url, const char *orig_url,
@ -52,7 +52,7 @@ void terminal_util_open_url (GtkWidget *parent,
guint32 user_time); guint32 user_time);
char *terminal_util_resolve_relative_path (const char *path, char *terminal_util_resolve_relative_path (const char *path,
const char *relative_path); const char *relative_path);
void terminal_util_transform_uris_to_quoted_fuse_paths (char **uris); void terminal_util_transform_uris_to_quoted_fuse_paths (char **uris);
@ -62,46 +62,47 @@ char *terminal_util_concat_uris (char **uris,
char *terminal_util_get_licence_text (void); char *terminal_util_get_licence_text (void);
gboolean terminal_util_load_builder_file (const char *filename, gboolean terminal_util_load_builder_file (const char *filename,
const char *object_name, const char *object_name,
...); ...);
gboolean terminal_util_dialog_response_on_delete (GtkWindow *widget); gboolean terminal_util_dialog_response_on_delete (GtkWindow *widget);
void terminal_util_key_file_set_string_escape (GKeyFile *key_file, void terminal_util_key_file_set_string_escape (GKeyFile *key_file,
const char *group, const char *group,
const char *key, const char *key,
const char *string); const char *string);
char *terminal_util_key_file_get_string_unescape (GKeyFile *key_file, char *terminal_util_key_file_get_string_unescape (GKeyFile *key_file,
const char *group, const char *group,
const char *key, const char *key,
GError **error); GError **error);
void terminal_util_key_file_set_argv (GKeyFile *key_file, void terminal_util_key_file_set_argv (GKeyFile *key_file,
const char *group, const char *group,
const char *key, const char *key,
int argc, int argc,
char **argv); char **argv);
char **terminal_util_key_file_get_argv (GKeyFile *key_file, char **terminal_util_key_file_get_argv (GKeyFile *key_file,
const char *group, const char *group,
const char *key, const char *key,
int *argc, int *argc,
GError **error); GError **error);
void terminal_util_add_proxy_env (GHashTable *env_table); void terminal_util_add_proxy_env (GHashTable *env_table);
typedef enum { typedef enum
FLAG_INVERT_BOOL = 1 << 0, {
FLAG_INVERT_BOOL = 1 << 0,
} PropertyChangeFlags; } PropertyChangeFlags;
void terminal_util_bind_object_property_to_widget (GObject *object, void terminal_util_bind_object_property_to_widget (GObject *object,
const char *object_prop, const char *object_prop,
GtkWidget *widget, GtkWidget *widget,
PropertyChangeFlags flags); PropertyChangeFlags flags);
gboolean terminal_util_x11_get_net_wm_desktop (GdkWindow *window, gboolean terminal_util_x11_get_net_wm_desktop (GdkWindow *window,
guint32 *desktop); guint32 *desktop);
void terminal_util_x11_set_net_wm_desktop (GdkWindow *window, void terminal_util_x11_set_net_wm_desktop (GdkWindow *window,
guint32 desktop); guint32 desktop);
void terminal_util_x11_clear_demands_attention (GdkWindow *window); void terminal_util_x11_clear_demands_attention (GdkWindow *window);

File diff suppressed because it is too large Load Diff

View File

@ -38,14 +38,14 @@ typedef struct _TerminalWindowPrivate TerminalWindowPrivate;
struct _TerminalWindow struct _TerminalWindow
{ {
GtkWindow parent_instance; GtkWindow parent_instance;
TerminalWindowPrivate *priv; TerminalWindowPrivate *priv;
}; };
struct _TerminalWindowClass struct _TerminalWindowClass
{ {
GtkWindowClass parent_class; GtkWindowClass parent_class;
}; };
@ -74,11 +74,11 @@ void terminal_window_move_screen (TerminalWindow *source_window,
* from the profile of the first screen added to the window * from the profile of the first screen added to the window
*/ */
void terminal_window_set_menubar_visible (TerminalWindow *window, void terminal_window_set_menubar_visible (TerminalWindow *window,
gboolean setting); gboolean setting);
gboolean terminal_window_get_menubar_visible (TerminalWindow *window); gboolean terminal_window_get_menubar_visible (TerminalWindow *window);
void terminal_window_switch_screen (TerminalWindow *window, void terminal_window_switch_screen (TerminalWindow *window,
TerminalScreen *screen); TerminalScreen *screen);
TerminalScreen* terminal_window_get_active (TerminalWindow *window); TerminalScreen* terminal_window_get_active (TerminalWindow *window);
GList* terminal_window_list_screen_containers (TerminalWindow *window); GList* terminal_window_list_screen_containers (TerminalWindow *window);
@ -88,10 +88,10 @@ void terminal_window_set_size (TerminalWindow *window,
TerminalScreen *screen, TerminalScreen *screen,
gboolean even_if_mapped); gboolean even_if_mapped);
void terminal_window_set_size_force_grid (TerminalWindow *window, void terminal_window_set_size_force_grid (TerminalWindow *window,
TerminalScreen *screen, TerminalScreen *screen,
gboolean even_if_mapped, gboolean even_if_mapped,
int force_grid_width, int force_grid_width,
int force_grid_height); int force_grid_height);
GtkWidget* terminal_window_get_notebook (TerminalWindow *window); GtkWidget* terminal_window_get_notebook (TerminalWindow *window);

View File

@ -52,79 +52,84 @@ static char *
ay_to_string (GVariant *variant, ay_to_string (GVariant *variant,
GError **error) GError **error)
{ {
gsize len; gsize len;
const char *data; const char *data;
data = g_variant_get_fixed_array (variant, &len, sizeof (char)); data = g_variant_get_fixed_array (variant, &len, sizeof (char));
if (len == 0) if (len == 0)
return NULL; return NULL;
/* Make sure there are no embedded NULs */ /* Make sure there are no embedded NULs */
if (memchr (data, '\0', len) != NULL) { if (memchr (data, '\0', len) != NULL)
g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, {
"String is shorter than claimed"); g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
return NULL; "String is shorter than claimed");
} return NULL;
}
return g_strndup (data, len); return g_strndup (data, len);
} }
static char ** static char **
ay_to_strv (GVariant *variant, ay_to_strv (GVariant *variant,
int *argc) int *argc)
{ {
GPtrArray *argv; GPtrArray *argv;
const char *data, *nullbyte; const char *data, *nullbyte;
gsize data_len; gsize data_len;
gssize len; gssize len;
data = g_variant_get_fixed_array (variant, &data_len, sizeof (char)); data = g_variant_get_fixed_array (variant, &data_len, sizeof (char));
if (data_len == 0 || data_len > G_MAXSSIZE) { if (data_len == 0 || data_len > G_MAXSSIZE)
*argc = 0; {
return NULL; *argc = 0;
} return NULL;
}
argv = g_ptr_array_new (); argv = g_ptr_array_new ();
len = data_len; len = data_len;
do { do
gssize string_len; {
gssize string_len;
nullbyte = memchr (data, '\0', len); nullbyte = memchr (data, '\0', len);
string_len = nullbyte ? (gssize) (nullbyte - data) : len; string_len = nullbyte ? (gssize) (nullbyte - data) : len;
g_ptr_array_add (argv, g_strndup (data, string_len)); g_ptr_array_add (argv, g_strndup (data, string_len));
len -= string_len + 1; len -= string_len + 1;
data += string_len + 1; data += string_len + 1;
} while (len > 0); }
while (len > 0);
if (argc) if (argc)
*argc = argv->len; *argc = argv->len;
/* NULL terminate */ /* NULL terminate */
g_ptr_array_add (argv, NULL); g_ptr_array_add (argv, NULL);
return (char **) g_ptr_array_free (argv, FALSE); return (char **) g_ptr_array_free (argv, FALSE);
} }
static GVariant * static GVariant *
string_to_ay (const char *string) string_to_ay (const char *string)
{ {
gsize len; gsize len;
char *data; char *data;
len = strlen (string); len = strlen (string);
data = g_strndup (string, len); data = g_strndup (string, len);
return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, len, TRUE, g_free, data); return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, len, TRUE, g_free, data);
} }
typedef struct { typedef struct
char *factory_name; {
TerminalOptions *options; char *factory_name;
int exit_code; TerminalOptions *options;
char **argv; int exit_code;
int argc; char **argv;
int argc;
} OwnData; } OwnData;
static void static void
@ -137,69 +142,74 @@ method_call_cb (GDBusConnection *connection,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
gpointer user_data) gpointer user_data)
{ {
if (g_strcmp0 (method_name, "HandleArguments") == 0) { if (g_strcmp0 (method_name, "HandleArguments") == 0)
TerminalOptions *options = NULL; {
GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv; TerminalOptions *options = NULL;
char *working_directory = NULL, *display_name = NULL, *startup_id = NULL; GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
char **envv = NULL, **argv = NULL; char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
int argc; char **envv = NULL, **argv = NULL;
GError *error = NULL; int argc;
GError *error = NULL;
g_variant_get (parameters, "(@ay@ay@ay@ay@ay)", g_variant_get (parameters, "(@ay@ay@ay@ay@ay)",
&v_wd, &v_display, &v_sid, &v_envv, &v_argv); &v_wd, &v_display, &v_sid, &v_envv, &v_argv);
working_directory = ay_to_string (v_wd, &error); working_directory = ay_to_string (v_wd, &error);
if (error) if (error)
goto out; goto out;
display_name = ay_to_string (v_display, &error); display_name = ay_to_string (v_display, &error);
if (error) if (error)
goto out; goto out;
startup_id = ay_to_string (v_sid, &error); startup_id = ay_to_string (v_sid, &error);
if (error) if (error)
goto out; goto out;
envv = ay_to_strv (v_envv, NULL); envv = ay_to_strv (v_envv, NULL);
argv = ay_to_strv (v_argv, &argc); argv = ay_to_strv (v_argv, &argc);
_terminal_debug_print (TERMINAL_DEBUG_FACTORY, _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
"Factory invoked with working-dir='%s' display='%s' startup-id='%s'\n", "Factory invoked with working-dir='%s' display='%s' startup-id='%s'\n",
working_directory ? working_directory : "(null)", working_directory ? working_directory : "(null)",
display_name ? display_name : "(null)", display_name ? display_name : "(null)",
startup_id ? startup_id : "(null)"); startup_id ? startup_id : "(null)");
options = terminal_options_parse (working_directory, options = terminal_options_parse (working_directory,
display_name, display_name,
startup_id, startup_id,
envv, envv,
TRUE, TRUE,
TRUE, TRUE,
&argc, &argv, &argc, &argv,
&error, &error,
NULL); NULL);
if (options != NULL) { if (options != NULL)
terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error); {
terminal_options_free (options); terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
} terminal_options_free (options);
}
out:
g_variant_unref (v_wd);
g_free (working_directory);
g_variant_unref (v_display);
g_free (display_name);
g_variant_unref (v_sid);
g_free (startup_id);
g_variant_unref (v_envv);
g_strfreev (envv);
g_variant_unref (v_argv);
g_strfreev (argv);
if (error == NULL) { out:
g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); g_variant_unref (v_wd);
} else { g_free (working_directory);
g_dbus_method_invocation_return_gerror (invocation, error); g_variant_unref (v_display);
g_error_free (error); g_free (display_name);
} g_variant_unref (v_sid);
} g_free (startup_id);
g_variant_unref (v_envv);
g_strfreev (envv);
g_variant_unref (v_argv);
g_strfreev (argv);
if (error == NULL)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
}
else
{
g_dbus_method_invocation_return_gerror (invocation, error);
g_error_free (error);
}
}
} }
static void static void
@ -207,50 +217,52 @@ bus_acquired_cb (GDBusConnection *connection,
const char *name, const char *name,
gpointer user_data) gpointer user_data)
{ {
static const char dbus_introspection_xml[] = static const char dbus_introspection_xml[] =
"<node name='/org/mate/Terminal'>" "<node name='/org/mate/Terminal'>"
"<interface name='org.mate.Terminal.Factory'>" "<interface name='org.mate.Terminal.Factory'>"
"<method name='HandleArguments'>" "<method name='HandleArguments'>"
"<arg type='ay' name='working_directory' direction='in' />" "<arg type='ay' name='working_directory' direction='in' />"
"<arg type='ay' name='display_name' direction='in' />" "<arg type='ay' name='display_name' direction='in' />"
"<arg type='ay' name='startup_id' direction='in' />" "<arg type='ay' name='startup_id' direction='in' />"
"<arg type='ay' name='environment' direction='in' />" "<arg type='ay' name='environment' direction='in' />"
"<arg type='ay' name='arguments' direction='in' />" "<arg type='ay' name='arguments' direction='in' />"
"</method>" "</method>"
"</interface>" "</interface>"
"</node>"; "</node>";
static const GDBusInterfaceVTable interface_vtable = { static const GDBusInterfaceVTable interface_vtable =
method_call_cb, {
NULL, method_call_cb,
NULL, NULL,
}; NULL,
};
OwnData *data = (OwnData *) user_data; OwnData *data = (OwnData *) user_data;
GDBusNodeInfo *introspection_data; GDBusNodeInfo *introspection_data;
guint registration_id; guint registration_id;
GError *error = NULL; GError *error = NULL;
_terminal_debug_print (TERMINAL_DEBUG_FACTORY, _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
"Bus %s acquired\n", name); "Bus %s acquired\n", name);
introspection_data = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL); introspection_data = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL);
g_assert (introspection_data != NULL); g_assert (introspection_data != NULL);
registration_id = g_dbus_connection_register_object (connection, registration_id = g_dbus_connection_register_object (connection,
TERMINAL_FACTORY_SERVICE_PATH, TERMINAL_FACTORY_SERVICE_PATH,
introspection_data->interfaces[0], introspection_data->interfaces[0],
&interface_vtable, &interface_vtable,
NULL, NULL, NULL, NULL,
&error); &error);
g_dbus_node_info_unref (introspection_data); g_dbus_node_info_unref (introspection_data);
if (registration_id == 0) { if (registration_id == 0)
g_printerr ("Failed to register object: %s\n", error->message); {
g_error_free (error); g_printerr ("Failed to register object: %s\n", error->message);
data->exit_code = EXIT_FAILURE; g_error_free (error);
gtk_main_quit (); data->exit_code = EXIT_FAILURE;
} gtk_main_quit ();
}
} }
static void static void
@ -258,27 +270,29 @@ name_acquired_cb (GDBusConnection *connection,
const char *name, const char *name,
gpointer user_data) gpointer user_data)
{ {
OwnData *data = (OwnData *) user_data; OwnData *data = (OwnData *) user_data;
GError *error = NULL; GError *error = NULL;
_terminal_debug_print (TERMINAL_DEBUG_FACTORY, _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
"Acquired the name %s on the session bus\n", name); "Acquired the name %s on the session bus\n", name);
if (data->options == NULL) { if (data->options == NULL)
/* Name re-acquired!? */ {
g_assert_not_reached (); /* Name re-acquired!? */
} g_assert_not_reached ();
}
if (!terminal_app_handle_options (terminal_app_get (), data->options, TRUE /* do resume */, &error)) { if (!terminal_app_handle_options (terminal_app_get (), data->options, TRUE /* do resume */, &error))
g_printerr ("Failed to handle options: %s\n", error->message); {
g_error_free (error); g_printerr ("Failed to handle options: %s\n", error->message);
data->exit_code = EXIT_FAILURE; g_error_free (error);
gtk_main_quit (); data->exit_code = EXIT_FAILURE;
} gtk_main_quit ();
}
terminal_options_free (data->options); terminal_options_free (data->options);
data->options = NULL; data->options = NULL;
} }
static void static void
@ -286,103 +300,108 @@ name_lost_cb (GDBusConnection *connection,
const char *name, const char *name,
gpointer user_data) gpointer user_data)
{ {
OwnData *data = (OwnData *) user_data; OwnData *data = (OwnData *) user_data;
GError *error = NULL; GError *error = NULL;
char **envv; char **envv;
int envc, i; int envc, i;
GVariantBuilder builder; GVariantBuilder builder;
GVariant *value; GVariant *value;
GString *string; GString *string;
char *s; char *s;
gsize len; gsize len;
_terminal_debug_print (TERMINAL_DEBUG_FACTORY, _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
"Lost the name %s on the session bus\n", name); "Lost the name %s on the session bus\n", name);
/* Couldn't get the connection? No way to continue! */ /* Couldn't get the connection? No way to continue! */
if (connection == NULL) { if (connection == NULL)
data->exit_code = EXIT_FAILURE; {
gtk_main_quit (); data->exit_code = EXIT_FAILURE;
return; gtk_main_quit ();
} return;
}
if (data->options == NULL) { if (data->options == NULL)
/* Already handled */ {
data->exit_code = EXIT_SUCCESS; /* Already handled */
gtk_main_quit (); data->exit_code = EXIT_SUCCESS;
return; gtk_main_quit ();
} return;
}
_terminal_debug_print (TERMINAL_DEBUG_FACTORY, _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
"Forwarding arguments to existing instance\n"); "Forwarding arguments to existing instance\n");
g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ayayayayay)")); g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ayayayayay)"));
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->default_working_dir)); g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->default_working_dir));
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->display_name)); g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->display_name));
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->startup_id)); g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->startup_id));
string = g_string_new (NULL); string = g_string_new (NULL);
envv = g_listenv (); envv = g_listenv ();
envc = g_strv_length (envv); envc = g_strv_length (envv);
for (i = 0; i < envc; ++i) for (i = 0; i < envc; ++i)
{ {
const char *value; const char *value;
value = g_getenv (envv[i]); value = g_getenv (envv[i]);
if (value == NULL) if (value == NULL)
continue; continue;
if (i > 0) if (i > 0)
g_string_append_c (string, '\0'); g_string_append_c (string, '\0');
g_string_append_printf (string, "%s=%s", envv[i], value); g_string_append_printf (string, "%s=%s", envv[i], value);
} }
len = string->len; len = string->len;
s = g_string_free (string, FALSE); s = g_string_free (string, FALSE);
g_variant_builder_add (&builder, "@ay", g_variant_builder_add (&builder, "@ay",
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s)); g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
string = g_string_new (NULL); string = g_string_new (NULL);
for (i = 0; i < data->argc; ++i) for (i = 0; i < data->argc; ++i)
{ {
if (i > 0) if (i > 0)
g_string_append_c (string, '\0'); g_string_append_c (string, '\0');
g_string_append (string, data->argv[i]); g_string_append (string, data->argv[i]);
} }
len = string->len; len = string->len;
s = g_string_free (string, FALSE); s = g_string_free (string, FALSE);
g_variant_builder_add (&builder, "@ay", g_variant_builder_add (&builder, "@ay",
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s)); g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
value = g_dbus_connection_call_sync (connection, value = g_dbus_connection_call_sync (connection,
data->factory_name, data->factory_name,
TERMINAL_FACTORY_SERVICE_PATH, TERMINAL_FACTORY_SERVICE_PATH,
TERMINAL_FACTORY_INTERFACE_NAME, TERMINAL_FACTORY_INTERFACE_NAME,
"HandleArguments", "HandleArguments",
g_variant_builder_end (&builder), g_variant_builder_end (&builder),
G_VARIANT_TYPE ("()"), G_VARIANT_TYPE ("()"),
G_DBUS_CALL_FLAGS_NONE, G_DBUS_CALL_FLAGS_NONE,
-1, -1,
NULL, NULL,
&error); &error);
if (value == NULL) { if (value == NULL)
g_printerr ("Failed to forward arguments: %s\n", error->message); {
g_error_free (error); g_printerr ("Failed to forward arguments: %s\n", error->message);
data->exit_code = EXIT_FAILURE; g_error_free (error);
gtk_main_quit (); data->exit_code = EXIT_FAILURE;
} else { gtk_main_quit ();
g_variant_unref (value); }
data->exit_code = EXIT_SUCCESS; else
} {
g_variant_unref (value);
data->exit_code = EXIT_SUCCESS;
}
terminal_options_free (data->options); terminal_options_free (data->options);
data->options = NULL; data->options = NULL;
gtk_main_quit (); gtk_main_quit ();
} }
/* Settings storage works as follows: /* Settings storage works as follows:
@ -413,207 +432,214 @@ name_lost_cb (GDBusConnection *connection,
static Time static Time
slowly_and_stupidly_obtain_timestamp (Display *xdisplay) slowly_and_stupidly_obtain_timestamp (Display *xdisplay)
{ {
Window xwindow; Window xwindow;
XEvent event; XEvent event;
{ {
XSetWindowAttributes attrs; XSetWindowAttributes attrs;
Atom atom_name; Atom atom_name;
Atom atom_type; Atom atom_type;
const char *name; const char *name;
attrs.override_redirect = True; attrs.override_redirect = True;
attrs.event_mask = PropertyChangeMask | StructureNotifyMask; attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
xwindow = xwindow =
XCreateWindow (xdisplay, XCreateWindow (xdisplay,
RootWindow (xdisplay, 0), RootWindow (xdisplay, 0),
-100, -100, 1, 1, -100, -100, 1, 1,
0, 0,
CopyFromParent, CopyFromParent,
CopyFromParent, CopyFromParent,
(Visual *)CopyFromParent, (Visual *)CopyFromParent,
CWOverrideRedirect | CWEventMask, CWOverrideRedirect | CWEventMask,
&attrs); &attrs);
atom_name = XInternAtom (xdisplay, "WM_NAME", TRUE); atom_name = XInternAtom (xdisplay, "WM_NAME", TRUE);
g_assert (atom_name != None); g_assert (atom_name != None);
atom_type = XInternAtom (xdisplay, "STRING", TRUE); atom_type = XInternAtom (xdisplay, "STRING", TRUE);
g_assert (atom_type != None); g_assert (atom_type != None);
name = "Fake Window"; name = "Fake Window";
XChangeProperty (xdisplay, XChangeProperty (xdisplay,
xwindow, atom_name, xwindow, atom_name,
atom_type, atom_type,
8, PropModeReplace, (unsigned char *)name, strlen (name)); 8, PropModeReplace, (unsigned char *)name, strlen (name));
} }
XWindowEvent (xdisplay, XWindowEvent (xdisplay,
xwindow, xwindow,
PropertyChangeMask, PropertyChangeMask,
&event); &event);
XDestroyWindow(xdisplay, xwindow); XDestroyWindow(xdisplay, xwindow);
return event.xproperty.time; return event.xproperty.time;
} }
static char * static char *
get_factory_name_for_display (const char *display_name) get_factory_name_for_display (const char *display_name)
{ {
GString *name; GString *name;
const char *p; const char *p;
name = g_string_sized_new (strlen (TERMINAL_FACTORY_SERVICE_NAME_PREFIX) + strlen (display_name) + 1 /* NUL */); name = g_string_sized_new (strlen (TERMINAL_FACTORY_SERVICE_NAME_PREFIX) + strlen (display_name) + 1 /* NUL */);
g_string_append (name, TERMINAL_FACTORY_SERVICE_NAME_PREFIX); g_string_append (name, TERMINAL_FACTORY_SERVICE_NAME_PREFIX);
for (p = display_name; *p; ++p) for (p = display_name; *p; ++p)
{ {
if (g_ascii_isalnum (*p)) if (g_ascii_isalnum (*p))
g_string_append_c (name, *p); g_string_append_c (name, *p);
else else
g_string_append_c (name, '_'); g_string_append_c (name, '_');
} }
_terminal_debug_print (TERMINAL_DEBUG_FACTORY, _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
"Factory name is \"%s\"\n", name->str); "Factory name is \"%s\"\n", name->str);
return g_string_free (name, FALSE); return g_string_free (name, FALSE);
} }
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
int i; int i;
char **argv_copy; char **argv_copy;
int argc_copy; int argc_copy;
const char *startup_id, *display_name, *home_dir; const char *startup_id, *display_name, *home_dir;
GdkDisplay *display; GdkDisplay *display;
TerminalOptions *options; TerminalOptions *options;
GError *error = NULL; GError *error = NULL;
char *working_directory; char *working_directory;
int ret = EXIT_SUCCESS; int ret = EXIT_SUCCESS;
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
bindtextdomain (GETTEXT_PACKAGE, TERM_LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, TERM_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE); textdomain (GETTEXT_PACKAGE);
/* MateConf uses MateCORBA2 which need GThread. See bug #565516 */ /* MateConf uses MateCORBA2 which need GThread. See bug #565516 */
g_thread_init (NULL); g_thread_init (NULL);
_terminal_debug_init (); _terminal_debug_init ();
/* Make a NULL-terminated copy since we may need it later */ /* Make a NULL-terminated copy since we may need it later */
argv_copy = g_new (char *, argc + 1); argv_copy = g_new (char *, argc + 1);
for (i = 0; i < argc; ++i) for (i = 0; i < argc; ++i)
argv_copy [i] = argv [i]; argv_copy [i] = argv [i];
argv_copy [i] = NULL; argv_copy [i] = NULL;
argc_copy = argc; argc_copy = argc;
startup_id = g_getenv ("DESKTOP_STARTUP_ID"); startup_id = g_getenv ("DESKTOP_STARTUP_ID");
working_directory = g_get_current_dir (); working_directory = g_get_current_dir ();
/* Now change directory to $HOME so we don't prevent unmounting, e.g. if the /* Now change directory to $HOME so we don't prevent unmounting, e.g. if the
* factory is started by caja-open-terminal. See bug #565328. * factory is started by caja-open-terminal. See bug #565328.
* On failure back to /. * On failure back to /.
*/ */
home_dir = g_get_home_dir (); home_dir = g_get_home_dir ();
if (home_dir == NULL || chdir (home_dir) < 0) if (home_dir == NULL || chdir (home_dir) < 0)
(void) chdir ("/"); (void) chdir ("/");
options = terminal_options_parse (working_directory, options = terminal_options_parse (working_directory,
NULL, NULL,
startup_id, startup_id,
NULL, NULL,
FALSE, FALSE,
FALSE, FALSE,
&argc, &argv, &argc, &argv,
&error, &error,
gtk_get_option_group (TRUE), gtk_get_option_group (TRUE),
#ifdef WITH_SMCLIENT #ifdef WITH_SMCLIENT
egg_sm_client_get_option_group (), egg_sm_client_get_option_group (),
#endif #endif
NULL); NULL);
g_free (working_directory); g_free (working_directory);
if (options == NULL) { if (options == NULL)
g_printerr (_("Failed to parse arguments: %s\n"), error->message); {
g_error_free (error); g_printerr (_("Failed to parse arguments: %s\n"), error->message);
exit (EXIT_FAILURE); g_error_free (error);
} exit (EXIT_FAILURE);
}
g_set_application_name (_("Terminal")); g_set_application_name (_("Terminal"));
/* Unset the these env variables, so they doesn't end up
* in the factory's env and thus in the terminals' envs.
*/
g_unsetenv ("DESKTOP_STARTUP_ID");
g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE_PID");
g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE");
/* Do this here so that gdk_display is initialized */ /* Unset the these env variables, so they doesn't end up
if (options->startup_id == NULL) * in the factory's env and thus in the terminals' envs.
{ */
/* Create a fake one containing a timestamp that we can use */ g_unsetenv ("DESKTOP_STARTUP_ID");
Time timestamp; g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE_PID");
g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE");
timestamp = slowly_and_stupidly_obtain_timestamp (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); /* Do this here so that gdk_display is initialized */
if (options->startup_id == NULL)
{
/* Create a fake one containing a timestamp that we can use */
Time timestamp;
options->startup_id = g_strdup_printf ("_TIME%lu", timestamp); timestamp = slowly_and_stupidly_obtain_timestamp (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
}
display = gdk_display_get_default (); options->startup_id = g_strdup_printf ("_TIME%lu", timestamp);
display_name = gdk_display_get_name (display); }
options->display_name = g_strdup (display_name);
if (options->use_factory) {
OwnData *data;
guint owner_id;
data = g_new (OwnData, 1); display = gdk_display_get_default ();
data->factory_name = get_factory_name_for_display (display_name); display_name = gdk_display_get_name (display);
data->options = options; options->display_name = g_strdup (display_name);
data->exit_code = -1;
data->argv = argv_copy;
data->argc = argc_copy;
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, if (options->use_factory)
data->factory_name, {
G_BUS_NAME_OWNER_FLAGS_NONE, OwnData *data;
bus_acquired_cb, guint owner_id;
name_acquired_cb,
name_lost_cb,
data, NULL);
gtk_main (); data = g_new (OwnData, 1);
data->factory_name = get_factory_name_for_display (display_name);
data->options = options;
data->exit_code = -1;
data->argv = argv_copy;
data->argc = argc_copy;
ret = data->exit_code; owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
g_bus_unown_name (owner_id); data->factory_name,
G_BUS_NAME_OWNER_FLAGS_NONE,
bus_acquired_cb,
name_acquired_cb,
name_lost_cb,
data, NULL);
g_free (data->factory_name); gtk_main ();
g_free (data);
} else { ret = data->exit_code;
g_bus_unown_name (owner_id);
terminal_app_handle_options (terminal_app_get (), options, TRUE /* allow resume */, &error); g_free (data->factory_name);
terminal_options_free (options); g_free (data);
if (error == NULL) { }
gtk_main (); else
} else { {
g_printerr ("Error handling options: %s\n", error->message);
g_error_free (error);
ret = EXIT_FAILURE;
}
}
terminal_app_shutdown (); terminal_app_handle_options (terminal_app_get (), options, TRUE /* allow resume */, &error);
terminal_options_free (options);
g_free (argv_copy); if (error == NULL)
{
gtk_main ();
}
else
{
g_printerr ("Error handling options: %s\n", error->message);
g_error_free (error);
ret = EXIT_FAILURE;
}
}
return ret; terminal_app_shutdown ();
g_free (argv_copy);
return ret;
} }