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 enum {
EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED,
typedef enum
{
EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED,
EGG_DESKTOP_FILE_TYPE_APPLICATION,
EGG_DESKTOP_FILE_TYPE_LINK,
EGG_DESKTOP_FILE_TYPE_DIRECTORY
EGG_DESKTOP_FILE_TYPE_APPLICATION,
EGG_DESKTOP_FILE_TYPE_LINK,
EGG_DESKTOP_FILE_TYPE_DIRECTORY
} EggDesktopFileType;
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,
GError **error);
GError **error);
EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path,
const char **search_dirs,
GError **error);
const char **search_dirs,
GError **error);
EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file,
const char *source,
GError **error);
const char *source,
GError **error);
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);
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_multiple (EggDesktopFile *desktop_file);
gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file);
char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file,
GSList *documents,
GError **error);
GSList *documents,
GError **error);
gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file,
GSList *documents,
GError **error,
...) G_GNUC_NULL_TERMINATED;
GSList *documents,
GError **error,
...) G_GNUC_NULL_TERMINATED;
typedef enum {
EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1,
EGG_DESKTOP_FILE_LAUNCH_PUTENV,
EGG_DESKTOP_FILE_LAUNCH_SCREEN,
EGG_DESKTOP_FILE_LAUNCH_WORKSPACE,
EGG_DESKTOP_FILE_LAUNCH_DIRECTORY,
EGG_DESKTOP_FILE_LAUNCH_TIME,
EGG_DESKTOP_FILE_LAUNCH_FLAGS,
EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC,
EGG_DESKTOP_FILE_LAUNCH_RETURN_PID,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID
typedef enum
{
EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1,
EGG_DESKTOP_FILE_LAUNCH_PUTENV,
EGG_DESKTOP_FILE_LAUNCH_SCREEN,
EGG_DESKTOP_FILE_LAUNCH_WORKSPACE,
EGG_DESKTOP_FILE_LAUNCH_DIRECTORY,
EGG_DESKTOP_FILE_LAUNCH_TIME,
EGG_DESKTOP_FILE_LAUNCH_FLAGS,
EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC,
EGG_DESKTOP_FILE_LAUNCH_RETURN_PID,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE,
EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID
} EggDesktopFileLaunchOption;
/* Standard Keys */
@ -112,30 +114,30 @@ typedef enum {
/* Accessors */
gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file,
const char *key,
GError **error);
const char *key,
GError **error);
char *egg_desktop_file_get_string (EggDesktopFile *desktop_file,
const char *key,
GError **error) G_GNUC_MALLOC;
const char *key,
GError **error) G_GNUC_MALLOC;
char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file,
const char *key,
const char *locale,
GError **error) G_GNUC_MALLOC;
const char *key,
const char *locale,
GError **error) G_GNUC_MALLOC;
gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file,
const char *key,
GError **error);
const char *key,
GError **error);
double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file,
const char *key,
GError **error);
const char *key,
GError **error);
char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file,
const char *key,
gsize *length,
GError **error) G_GNUC_MALLOC;
const char *key,
gsize *length,
GError **error) G_GNUC_MALLOC;
char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file,
const char *key,
const char *locale,
gsize *length,
GError **error) G_GNUC_MALLOC;
const char *key,
const char *locale,
gsize *length,
GError **error) G_GNUC_MALLOC;
/* Errors */
@ -143,10 +145,11 @@ char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file
GQuark egg_desktop_file_error_quark (void);
typedef enum {
EGG_DESKTOP_FILE_ERROR_INVALID,
EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
typedef enum
{
EGG_DESKTOP_FILE_ERROR_INVALID,
EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
} EggDesktopFileError;
/* Global application desktop file */

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -26,22 +26,24 @@
#include "eggsmclient-private.h"
static void egg_sm_client_debug_handler (const char *log_domain,
GLogLevelFlags log_level,
const char *message,
gpointer user_data);
GLogLevelFlags log_level,
const char *message,
gpointer user_data);
enum {
SAVE_STATE,
QUIT_REQUESTED,
QUIT_CANCELLED,
QUIT,
LAST_SIGNAL
enum
{
SAVE_STATE,
QUIT_REQUESTED,
QUIT_CANCELLED,
QUIT,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
struct _EggSMClientPrivate {
GKeyFile *state_file;
struct _EggSMClientPrivate
{
GKeyFile *state_file;
};
#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
egg_sm_client_init (EggSMClient *client)
{
;
;
}
static void
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:
* @client: the client
* @state_file: a #GKeyFile to save state information into
*
* Emitted when the session manager has requested that the
* application save information about its current state. The
* application should save its state into @state_file, and then the
* session manager may then restart the application in a future
* session and tell it to initialize itself from that state.
*
* You should not save any data into @state_file's "start group"
* (ie, the %NULL group). Instead, applications should save their
* data into groups with names that start with the application name,
* and libraries that connect to this signal should save their data
* into groups with names that start with the library name.
*
* Alternatively, rather than (or in addition to) using @state_file,
* the application can save its state by calling
* egg_sm_client_set_restart_command() during the processing of this
* signal (eg, to include a list of files to open).
**/
signals[SAVE_STATE] =
g_signal_new ("save_state",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, save_state),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1, G_TYPE_POINTER);
/**
* EggSMClient::save_state:
* @client: the client
* @state_file: a #GKeyFile to save state information into
*
* Emitted when the session manager has requested that the
* application save information about its current state. The
* application should save its state into @state_file, and then the
* session manager may then restart the application in a future
* session and tell it to initialize itself from that state.
*
* You should not save any data into @state_file's "start group"
* (ie, the %NULL group). Instead, applications should save their
* data into groups with names that start with the application name,
* and libraries that connect to this signal should save their data
* into groups with names that start with the library name.
*
* Alternatively, rather than (or in addition to) using @state_file,
* the application can save its state by calling
* egg_sm_client_set_restart_command() during the processing of this
* signal (eg, to include a list of files to open).
**/
signals[SAVE_STATE] =
g_signal_new ("save_state",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, save_state),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1, G_TYPE_POINTER);
/**
* EggSMClient::quit_requested:
* @client: the client
*
* Emitted when the session manager requests that the application
* exit (generally because the user is logging out). The application
* should decide whether or not it is willing to quit (perhaps after
* asking the user what to do with documents that have unsaved
* changes) and then call egg_sm_client_will_quit(), passing %TRUE
* or %FALSE to give its answer to the session manager. (It does not
* need to give an answer before returning from the signal handler;
* it can interact with the user asynchronously and then give its
* answer later on.) If the application does not connect to this
* signal, then #EggSMClient will automatically return %TRUE on its
* behalf.
*
* The application should not save its session state as part of
* handling this signal; if the user has requested that the session
* be saved when logging out, then ::save_state will be emitted
* separately.
*
* If the application agrees to quit, it should then wait for either
* the ::quit_cancelled or ::quit signals to be emitted.
**/
signals[QUIT_REQUESTED] =
g_signal_new ("quit_requested",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, quit_requested),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* EggSMClient::quit_requested:
* @client: the client
*
* Emitted when the session manager requests that the application
* exit (generally because the user is logging out). The application
* should decide whether or not it is willing to quit (perhaps after
* asking the user what to do with documents that have unsaved
* changes) and then call egg_sm_client_will_quit(), passing %TRUE
* or %FALSE to give its answer to the session manager. (It does not
* need to give an answer before returning from the signal handler;
* it can interact with the user asynchronously and then give its
* answer later on.) If the application does not connect to this
* signal, then #EggSMClient will automatically return %TRUE on its
* behalf.
*
* The application should not save its session state as part of
* handling this signal; if the user has requested that the session
* be saved when logging out, then ::save_state will be emitted
* separately.
*
* If the application agrees to quit, it should then wait for either
* the ::quit_cancelled or ::quit signals to be emitted.
**/
signals[QUIT_REQUESTED] =
g_signal_new ("quit_requested",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, quit_requested),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* EggSMClient::quit_cancelled:
* @client: the client
*
* Emitted when the session manager decides to cancel a logout after
* the application has already agreed to quit. After receiving this
* signal, the application can go back to what it was doing before
* receiving the ::quit_requested signal.
**/
signals[QUIT_CANCELLED] =
g_signal_new ("quit_cancelled",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* EggSMClient::quit_cancelled:
* @client: the client
*
* Emitted when the session manager decides to cancel a logout after
* the application has already agreed to quit. After receiving this
* signal, the application can go back to what it was doing before
* receiving the ::quit_requested signal.
**/
signals[QUIT_CANCELLED] =
g_signal_new ("quit_cancelled",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* EggSMClient::quit:
* @client: the client
*
* Emitted when the session manager wants the application to quit
* (generally because the user is logging out). The application
* should exit as soon as possible after receiving this signal; if
* it does not, the session manager may choose to forcibly kill it.
*
* Normally a GUI application would only be sent a ::quit if it
* agreed to quit in response to a ::quit_requested signal. However,
* this is not guaranteed; in some situations the session manager
* may decide to end the session without giving applications a
* chance to object.
**/
signals[QUIT] =
g_signal_new ("quit",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, quit),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* EggSMClient::quit:
* @client: the client
*
* Emitted when the session manager wants the application to quit
* (generally because the user is logging out). The application
* should exit as soon as possible after receiving this signal; if
* it does not, the session manager may choose to forcibly kill it.
*
* Normally a GUI application would only be sent a ::quit if it
* agreed to quit in response to a ::quit_requested signal. However,
* this is not guaranteed; in some situations the session manager
* may decide to end the session without giving applications a
* chance to object.
**/
signals[QUIT] =
g_signal_new ("quit",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EggSMClientClass, quit),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
}
static gboolean sm_client_disable = FALSE;
@ -182,29 +184,29 @@ static char *sm_config_prefix = NULL;
static gboolean
sm_client_post_parse_func (GOptionContext *context,
GOptionGroup *group,
gpointer data,
GError **error)
GOptionGroup *group,
gpointer data,
GError **error)
{
EggSMClient *client = egg_sm_client_get ();
EggSMClient *client = egg_sm_client_get ();
if (sm_client_id == NULL)
{
const gchar *desktop_autostart_id;
if (sm_client_id == NULL)
{
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)
sm_client_id = g_strdup (desktop_autostart_id);
}
if (desktop_autostart_id != NULL)
sm_client_id = g_strdup (desktop_autostart_id);
}
/* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
* use the same client id. */
g_unsetenv ("DESKTOP_AUTOSTART_ID");
/* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
* use the same client id. */
g_unsetenv ("DESKTOP_AUTOSTART_ID");
if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
return TRUE;
if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
return TRUE;
}
/**
@ -219,43 +221,54 @@ sm_client_post_parse_func (GOptionContext *context,
GOptionGroup *
egg_sm_client_get_option_group (void)
{
const GOptionEntry entries[] = {
{ "sm-client-disable", 0, 0,
G_OPTION_ARG_NONE, &sm_client_disable,
N_("Disable connection to session manager"), NULL },
{ "sm-client-state-file", 0, 0,
G_OPTION_ARG_FILENAME, &sm_client_state_file,
N_("Specify file containing saved configuration"), N_("FILE") },
{ "sm-client-id", 0, 0,
G_OPTION_ARG_STRING, &sm_client_id,
N_("Specify session management ID"), N_("ID") },
/* MateClient compatibility option */
{ "sm-disable", 0, G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_NONE, &sm_client_disable,
NULL, NULL },
/* 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;
const GOptionEntry entries[] =
{
{
"sm-client-disable", 0, 0,
G_OPTION_ARG_NONE, &sm_client_disable,
N_("Disable connection to session manager"), NULL
},
{
"sm-client-state-file", 0, 0,
G_OPTION_ARG_FILENAME, &sm_client_state_file,
N_("Specify file containing saved configuration"), N_("FILE")
},
{
"sm-client-id", 0, 0,
G_OPTION_ARG_STRING, &sm_client_id,
N_("Specify session management ID"), N_("ID")
},
/* MateClient compatibility option */
{
"sm-disable", 0, G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_NONE, &sm_client_disable,
NULL, NULL
},
/* 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. */
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
egg_sm_client_debug_handler, NULL);
/* Use our own debug handler for the "EggSMClient" domain. */
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
egg_sm_client_debug_handler, NULL);
group = g_option_group_new ("sm-client",
_("Session management options:"),
_("Show session management options"),
NULL, NULL);
g_option_group_add_entries (group, entries);
g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func);
group = g_option_group_new ("sm-client",
_("Session management options:"),
_("Show session management options"),
NULL, NULL);
g_option_group_add_entries (group, entries);
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
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
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 *
egg_sm_client_get (void)
{
if (!global_client)
{
if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
!sm_client_disable)
if (!global_client)
{
if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
!sm_client_disable)
{
#if defined (GDK_WINDOWING_WIN32)
global_client = egg_sm_client_win32_new ();
global_client = egg_sm_client_win32_new ();
#elif defined (GDK_WINDOWING_QUARTZ)
global_client = egg_sm_client_osx_new ();
global_client = egg_sm_client_osx_new ();
#else
/* If both D-Bus and XSMP are compiled in, try XSMP first
* (since it supports state saving) and fall back to D-Bus
* if XSMP isn't available.
*/
/* If both D-Bus and XSMP are compiled in, try XSMP first
* (since it supports state saving) and fall back to D-Bus
* if XSMP isn't available.
*/
# ifdef EGG_SM_CLIENT_BACKEND_XSMP
global_client = egg_sm_client_xsmp_new ();
global_client = egg_sm_client_xsmp_new ();
# endif
# ifdef EGG_SM_CLIENT_BACKEND_DBUS
if (!global_client)
global_client = egg_sm_client_dbus_new ();
if (!global_client)
global_client = egg_sm_client_dbus_new ();
# 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
* to worry about a %NULL return value.
*/
if (!global_client)
global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL);
}
return global_client;
return global_client;
}
/**
@ -363,9 +376,9 @@ egg_sm_client_get (void)
gboolean
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 *
egg_sm_client_get_state_file (EggSMClient *client)
{
EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client);
char *state_file_path;
GError *err = NULL;
EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client);
char *state_file_path;
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)
return NULL;
if (priv->state_file)
return priv->state_file;
if (!sm_client_state_file)
return NULL;
if (priv->state_file)
return priv->state_file;
if (!strncmp (sm_client_state_file, "file://", 7))
state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL);
else
state_file_path = g_strdup (sm_client_state_file);
if (!strncmp (sm_client_state_file, "file://", 7))
state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL);
else
state_file_path = g_strdup (sm_client_state_file);
priv->state_file = g_key_file_new ();
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",
sm_client_state_file, err->message);
g_clear_error (&err);
g_key_file_free (priv->state_file);
priv->state_file = NULL;
}
priv->state_file = g_key_file_new ();
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",
sm_client_state_file, err->message);
g_clear_error (&err);
g_key_file_free (priv->state_file);
priv->state_file = NULL;
}
g_free (state_file_path);
return priv->state_file;
g_free (state_file_path);
return priv->state_file;
}
/**
@ -435,13 +448,13 @@ egg_sm_client_get_state_file (EggSMClient *client)
**/
void
egg_sm_client_set_restart_command (EggSMClient *client,
int argc,
const char **argv)
int argc,
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)
EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv);
if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command)
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
*
* 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.
**/
void
egg_sm_client_set_discard_command (EggSMClient *client,
int argc,
const char **argv)
int argc,
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)
EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command (client, argc, argv);
if (EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command)
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
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)
EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit);
if (EGG_SM_CLIENT_GET_CLASS (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
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)
{
return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style,
request_confirmation);
}
else
return FALSE;
if (EGG_SM_CLIENT_GET_CLASS (client)->end_session)
{
return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style,
request_confirmation);
}
else
return FALSE;
}
/* Signal-emitting callbacks from platform-specific code */
@ -531,80 +544,80 @@ egg_sm_client_end_session (EggSMClientEndStyle style,
GKeyFile *
egg_sm_client_save_state (EggSMClient *client)
{
GKeyFile *state_file;
char *group;
GKeyFile *state_file;
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_signal_emit (client, signals[SAVE_STATE], 0, state_file);
g_debug ("Done emitting save_state");
g_debug ("Emitting save_state");
g_signal_emit (client, signals[SAVE_STATE], 0, state_file);
g_debug ("Done emitting save_state");
group = g_key_file_get_start_group (state_file);
if (group)
{
g_free (group);
return state_file;
}
else
{
g_key_file_free (state_file);
return NULL;
}
group = g_key_file_get_start_group (state_file);
if (group)
{
g_free (group);
return state_file;
}
else
{
g_key_file_free (state_file);
return NULL;
}
}
void
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))
{
g_debug ("Not emitting quit_requested because no one is listening");
egg_sm_client_will_quit (client, TRUE);
return;
}
if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE))
{
g_debug ("Not emitting quit_requested because no one is listening");
egg_sm_client_will_quit (client, TRUE);
return;
}
g_debug ("Emitting quit_requested");
g_signal_emit (client, signals[QUIT_REQUESTED], 0);
g_debug ("Done emitting quit_requested");
g_debug ("Emitting quit_requested");
g_signal_emit (client, signals[QUIT_REQUESTED], 0);
g_debug ("Done emitting quit_requested");
}
void
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_signal_emit (client, signals[QUIT_CANCELLED], 0);
g_debug ("Done emitting quit_cancelled");
g_debug ("Emitting quit_cancelled");
g_signal_emit (client, signals[QUIT_CANCELLED], 0);
g_debug ("Done emitting quit_cancelled");
}
void
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_signal_emit (client, signals[QUIT], 0);
g_debug ("Done emitting quit");
g_debug ("Emitting quit");
g_signal_emit (client, signals[QUIT], 0);
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
egg_sm_client_debug_handler (const char *log_domain,
GLogLevelFlags log_level,
const char *message,
gpointer user_data)
GLogLevelFlags log_level,
const char *message,
gpointer user_data)
{
static int debug = -1;
static int debug = -1;
if (debug < 0)
debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL);
if (debug < 0)
debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL);
if (debug)
g_log_default_handler (log_domain, log_level, message, NULL);
if (debug)
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 _EggSMClientPrivate EggSMClientPrivate;
typedef enum {
EGG_SM_CLIENT_END_SESSION_DEFAULT,
EGG_SM_CLIENT_LOGOUT,
EGG_SM_CLIENT_REBOOT,
EGG_SM_CLIENT_SHUTDOWN
typedef enum
{
EGG_SM_CLIENT_END_SESSION_DEFAULT,
EGG_SM_CLIENT_LOGOUT,
EGG_SM_CLIENT_REBOOT,
EGG_SM_CLIENT_SHUTDOWN
} EggSMClientEndStyle;
typedef enum {
EGG_SM_CLIENT_MODE_DISABLED,
EGG_SM_CLIENT_MODE_NO_RESTART,
EGG_SM_CLIENT_MODE_NORMAL
typedef enum
{
EGG_SM_CLIENT_MODE_DISABLED,
EGG_SM_CLIENT_MODE_NO_RESTART,
EGG_SM_CLIENT_MODE_NORMAL
} EggSMClientMode;
struct _EggSMClient
{
GObject parent;
GObject parent;
};
struct _EggSMClientClass
{
GObjectClass parent_class;
GObjectClass parent_class;
/* signals */
void (*save_state) (EggSMClient *client,
GKeyFile *state_file);
/* signals */
void (*save_state) (EggSMClient *client,
GKeyFile *state_file);
void (*quit_requested) (EggSMClient *client);
void (*quit_cancelled) (EggSMClient *client);
void (*quit) (EggSMClient *client);
void (*quit_requested) (EggSMClient *client);
void (*quit_cancelled) (EggSMClient *client);
void (*quit) (EggSMClient *client);
/* virtual methods */
void (*startup) (EggSMClient *client,
const char *client_id);
void (*set_restart_command) (EggSMClient *client,
int argc,
const char **argv);
void (*set_discard_command) (EggSMClient *client,
int argc,
const char **argv);
void (*will_quit) (EggSMClient *client,
gboolean will_quit);
gboolean (*end_session) (EggSMClient *client,
EggSMClientEndStyle style,
gboolean request_confirmation);
/* virtual methods */
void (*startup) (EggSMClient *client,
const char *client_id);
void (*set_restart_command) (EggSMClient *client,
int argc,
const char **argv);
void (*set_discard_command) (EggSMClient *client,
int argc,
const char **argv);
void (*will_quit) (EggSMClient *client,
gboolean will_quit);
gboolean (*end_session) (EggSMClient *client,
EggSMClientEndStyle style,
gboolean request_confirmation);
/* Padding for future expansion */
void (*_egg_reserved1) (void);
void (*_egg_reserved2) (void);
void (*_egg_reserved3) (void);
void (*_egg_reserved4) (void);
/* Padding for future expansion */
void (*_egg_reserved1) (void);
void (*_egg_reserved2) (void);
void (*_egg_reserved3) (void);
void (*_egg_reserved4) (void);
};
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 */
void egg_sm_client_set_restart_command (EggSMClient *client,
int argc,
const char **argv);
int argc,
const char **argv);
void egg_sm_client_set_discard_command (EggSMClient *client,
int argc,
const char **argv);
int argc,
const char **argv);
/* Handling "quit_requested" signal */
void egg_sm_client_will_quit (EggSMClient *client,
gboolean will_quit);
gboolean will_quit);
/* Initiate a logout/reboot/shutdown */
gboolean egg_sm_client_end_session (EggSMClientEndStyle style,
gboolean request_confirmation);
gboolean request_confirmation);
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 OTP_PREFIX "otp-"
typedef struct {
TerminalScreen *screen;
char *seed;
int seq;
int hash;
typedef struct
{
TerminalScreen *screen;
char *seed;
int seq;
int hash;
} SkeyData;
static void
skey_data_free (SkeyData *data)
{
g_free (data->seed);
g_free (data);
g_free (data->seed);
g_free (data);
}
static gboolean
extract_seq_and_seed (const gchar *skey_match,
gint *seq,
gchar **seed)
gint *seq,
gchar **seed)
{
gchar *end_ptr = NULL;
gchar *end_ptr = NULL;
/* FIXME: use g_ascii_strtoll */
*seq = strtol (skey_match + strlen (SKEY_PREFIX), &end_ptr, 0);
/* FIXME: use g_ascii_strtoll */
*seq = strtol (skey_match + strlen (SKEY_PREFIX), &end_ptr, 0);
if (end_ptr == NULL || *end_ptr == '\000')
return FALSE;
if (end_ptr == NULL || *end_ptr == '\000')
return FALSE;
*seed = g_strdup (end_ptr + 1);
*seed = g_strdup (end_ptr + 1);
return TRUE;
return TRUE;
}
static gboolean
extract_hash_seq_and_seed (const gchar *otp_match,
gint *hash,
gint *seq,
gchar **seed)
gint *hash,
gint *seq,
gchar **seed)
{
gchar *end_ptr = NULL;
const gchar *p = otp_match + strlen (OTP_PREFIX);
gint len = 3;
gchar *end_ptr = NULL;
const gchar *p = otp_match + strlen (OTP_PREFIX);
gint len = 3;
if (strncmp (p, "md4", 3) == 0)
*hash = MD4;
else if (strncmp (p, "md5", 3) == 0)
*hash = MD5;
else if (strncmp (p, "sha1", 4) == 0)
{
*hash = SHA1;
len++;
}
else
return FALSE;
if (strncmp (p, "md4", 3) == 0)
*hash = MD4;
else if (strncmp (p, "md5", 3) == 0)
*hash = MD5;
else if (strncmp (p, "sha1", 4) == 0)
{
*hash = SHA1;
len++;
}
else
return FALSE;
p += len;
p += len;
/* RFC mandates the following skipping */
while (*p == ' ' || *p == '\t')
{
if (*p == '\0')
return FALSE;
/* RFC mandates the following skipping */
while (*p == ' ' || *p == '\t')
{
if (*p == '\0')
return FALSE;
p++;
}
p++;
}
/* FIXME: use g_ascii_strtoll */
*seq = strtol (p, &end_ptr, 0);
/* FIXME: use g_ascii_strtoll */
*seq = strtol (p, &end_ptr, 0);
if (end_ptr == NULL || *end_ptr == '\000')
return FALSE;
if (end_ptr == NULL || *end_ptr == '\000')
return FALSE;
p = end_ptr;
p = end_ptr;
while (*p == ' ' || *p == '\t')
{
if (*p == '\0')
return FALSE;
p++;
}
while (*p == ' ' || *p == '\t')
{
if (*p == '\0')
return FALSE;
p++;
}
*seed = g_strdup (p);
return TRUE;
*seed = g_strdup (p);
return TRUE;
}
static void
skey_challenge_response_cb (GtkWidget *dialog,
int response_id,
SkeyData *data)
{
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)
{
if (response_id == GTK_RESPONSE_OK)
{
VteTerminal *vte_terminal = VTE_TERMINAL (data->screen);
static const char newline[2] = "\n";
GtkWidget *entry;
const char *password;
char *response;
vte_terminal_feed_child (vte_terminal, response, strlen (response));
vte_terminal_feed_child (vte_terminal, newline, strlen (newline));
free (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);
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
terminal_skey_do_popup (GtkWindow *window,
TerminalScreen *screen,
const gchar *skey_match)
const gchar *skey_match)
{
GtkWidget *dialog, *label, *entry, *ok_button;
char *title_text;
char *seed;
int seq;
int hash = MD5;
SkeyData *data;
GtkWidget *dialog, *label, *entry, *ok_button;
char *title_text;
char *seed;
int seq;
int hash = MD5;
SkeyData *data;
if (strncmp (SKEY_PREFIX, skey_match, strlen (SKEY_PREFIX)) == 0)
{
if (!extract_seq_and_seed (skey_match, &seq, &seed))
if (strncmp (SKEY_PREFIX, skey_match, strlen (SKEY_PREFIX)) == 0)
{
terminal_util_show_error_dialog (window, NULL, NULL,
_("The text you clicked on doesn't "
"seem to be a valid S/Key "
"challenge."));
return;
if (!extract_seq_and_seed (skey_match, &seq, &seed))
{
terminal_util_show_error_dialog (window, NULL, NULL,
_("The text you clicked on doesn't "
"seem to be a valid S/Key "
"challenge."));
return;
}
}
}
else
{
if (!extract_hash_seq_and_seed (skey_match, &hash, &seq, &seed))
else
{
terminal_util_show_error_dialog (window, NULL, NULL,
_("The text you clicked on doesn't "
"seem to be a valid OTP "
"challenge."));
return;
if (!extract_hash_seq_and_seed (skey_match, &hash, &seq, &seed))
{
terminal_util_show_error_dialog (window, NULL, NULL,
_("The text you clicked on doesn't "
"seem to be a valid OTP "
"challenge."));
return;
}
}
}
if (!terminal_util_load_builder_file ("skey-challenge.ui",
"skey-dialog", &dialog,
"skey-entry", &entry,
"text-label", &label,
"skey-ok-button", &ok_button,
NULL))
{
g_free (seed);
return;
}
if (!terminal_util_load_builder_file ("skey-challenge.ui",
"skey-dialog", &dialog,
"skey-entry", &entry,
"text-label", &label,
"skey-ok-button", &ok_button,
NULL))
{
g_free (seed);
return;
}
title_text = g_strdup_printf ("<big><b>%s</b></big>",
gtk_label_get_text (GTK_LABEL (label)));
gtk_label_set_label (GTK_LABEL (label), title_text);
g_free (title_text);
title_text = g_strdup_printf ("<big><b>%s</b></big>",
gtk_label_get_text (GTK_LABEL (label)));
gtk_label_set_label (GTK_LABEL (label), 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_default (ok_button);
gtk_entry_set_text (GTK_ENTRY (entry), "");
gtk_widget_grab_focus (entry);
gtk_widget_grab_default (ok_button);
gtk_entry_set_text (GTK_ENTRY (entry), "");
gtk_window_set_transient_for (GTK_WINDOW (dialog), window);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
gtk_window_set_transient_for (GTK_WINDOW (dialog), window);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-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->hash = hash;
data->seq = seq;
data->seed = seed;
data->screen = screen;
data = g_new (SkeyData, 1);
data->hash = hash;
data->seq = seq;
data->seed = seed;
data->screen = screen;
g_signal_connect_data (dialog, "response",
G_CALLBACK (skey_challenge_response_cb),
data, (GClosureNotify) skey_data_free, 0);
g_signal_connect (dialog, "delete-event",
G_CALLBACK (terminal_util_dialog_response_on_delete), NULL);
g_signal_connect_data (dialog, "response",
G_CALLBACK (skey_challenge_response_cb),
data, (GClosureNotify) skey_data_free, 0);
g_signal_connect (dialog, "delete-event",
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,
TerminalScreen *screen,
const gchar *skey_match);
const gchar *skey_match);
G_END_DECLS

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,8 +8,9 @@
#include "skey.h"
typedef struct {
SKeyAlgorithm algorithm;
typedef struct
{
SKeyAlgorithm algorithm;
const char *passphrase;
const char *seed;
int count;
@ -17,7 +18,8 @@ typedef struct {
const char *btoe;
} 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", 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" },
@ -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", 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[] = {
"MD4",
"MD5",
"SHA1"
static const char *algos[] =
{
"MD4",
"MD5",
"SHA1"
};
static void
skey_test (gconstpointer data)
{
const TestEntry *test = (const TestEntry *) data;
char *key;
const TestEntry *test = (const TestEntry *) data;
char *key;
key = skey (test->algorithm,
test->count,
test->seed,
test->passphrase);
g_assert (key != NULL);
g_assert (strcmp (key, test->btoe) == 0);
free (key);
key = skey (test->algorithm,
test->count,
test->seed,
test->passphrase);
g_assert (key != NULL);
g_assert (strcmp (key, test->btoe) == 0);
free (key);
}
int main(int argc, char *argv[])
{
guint i;
guint i;
if (!setlocale (LC_ALL, ""))
g_error ("Locale not supported by C library!\n");
if (!setlocale (LC_ALL, ""))
g_error ("Locale not supported by C library!\n");
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.mate.org/enter_bug.cgi?product=mate-terminal");
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.mate.org/enter_bug.cgi?product=mate-terminal");
for (i = 0; i < G_N_ELEMENTS (tests); ++i) {
const TestEntry *test = &tests[i];
char *name;
for (i = 0; i < G_N_ELEMENTS (tests); ++i)
{
const TestEntry *test = &tests[i];
char *name;
name = g_strdup_printf ("/%s/%s/%s/%d/%s/%s",
algos[test->algorithm],
test->passphrase,
test->seed,
test->count,
test->hex,
test->btoe);
g_test_add_data_func (name, test, skey_test);
g_free (name);
}
name = g_strdup_printf ("/%s/%s/%s/%d/%s/%s",
algos[test->algorithm],
test->passphrase,
test->seed,
test->count,
test->hex,
test->btoe);
g_test_add_data_func (name, test, skey_test);
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
void terminal_accels_init (void);
void terminal_accels_shutdown (void);
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);
TerminalWindow * terminal_app_new_window (TerminalApp *app,
GdkScreen *screen);
GdkScreen *screen);
TerminalScreen *terminal_app_new_terminal (TerminalApp *app,
TerminalWindow *window,
TerminalProfile *profile,
char **override_command,
const char *title,
const char *working_dir,
char **child_env,
double zoom);
TerminalWindow *window,
TerminalProfile *profile,
char **override_command,
const char *title,
const char *working_dir,
char **child_env,
double zoom);
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_get_profile_by_name (TerminalApp *app,
const char *name);
const char *name);
TerminalProfile* terminal_app_get_profile_by_visible_name (TerminalApp *app,
const char *name);
const char *name);
/* may return NULL */
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);
TerminalEncoding *terminal_app_ensure_encoding (TerminalApp *app,
const char *charset);
const char *charset);
GHashTable *terminal_app_get_encodings (TerminalApp *app);

View File

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

View File

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

View File

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

View File

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

View File

@ -26,7 +26,7 @@
struct _TerminalInfoBarPrivate
{
GtkWidget *content_box;
GtkWidget *content_box;
};
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
terminal_info_bar_init (TerminalInfoBar *bar)
{
GtkInfoBar *info_bar = GTK_INFO_BAR (bar);
TerminalInfoBarPrivate *priv;
GtkInfoBar *info_bar = GTK_INFO_BAR (bar);
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);
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (info_bar)),
priv->content_box, TRUE, TRUE, 0);
priv->content_box = gtk_vbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (info_bar)),
priv->content_box, TRUE, TRUE, 0);
}
static void
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 */
@ -67,26 +67,27 @@ terminal_info_bar_new (GtkMessageType type,
const char *first_button_text,
...)
{
GtkWidget *info_bar;
va_list args;
GtkWidget *info_bar;
va_list args;
info_bar = g_object_new (TERMINAL_TYPE_INFO_BAR,
"message-type", type,
NULL);
info_bar = g_object_new (TERMINAL_TYPE_INFO_BAR,
"message-type", type,
NULL);
va_start (args, first_button_text);
while (first_button_text != NULL) {
int response_id;
va_start (args, first_button_text);
while (first_button_text != NULL)
{
int response_id;
response_id = va_arg (args, int);
gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
first_button_text, response_id);
response_id = va_arg (args, int);
gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
first_button_text, response_id);
first_button_text = va_arg (args, const char *);
}
va_end (args);
first_button_text = va_arg (args, const char *);
}
va_end (args);
return info_bar;
return info_bar;
}
void
@ -94,26 +95,26 @@ terminal_info_bar_format_text (TerminalInfoBar *bar,
const char *format,
...)
{
TerminalInfoBarPrivate *priv;
char *text;
GtkWidget *label;
va_list args;
TerminalInfoBarPrivate *priv;
char *text;
GtkWidget *label;
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);
text = g_strdup_vprintf (format, args);
va_end (args);
va_start (args, format);
text = g_strdup_vprintf (format, args);
va_end (args);
label = gtk_label_new (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);
label = gtk_label_new (text);
g_free (text);
gtk_box_pack_start (GTK_BOX (priv->content_box), label, FALSE, FALSE, 0);
gtk_widget_show_all (priv->content_box);
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_widget_show_all (priv->content_box);
}

View File

@ -36,15 +36,15 @@ typedef struct _TerminalInfoBarPrivate TerminalInfoBarPrivate;
struct _TerminalInfoBar
{
GtkInfoBar parent_instance;
GtkInfoBar parent_instance;
/*< private >*/
TerminalInfoBarPrivate *priv;
/*< private >*/
TerminalInfoBarPrivate *priv;
};
struct _TerminalInfoBarClass
{
GtkInfoBarClass parent_class;
GtkInfoBarClass parent_class;
};
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
{
gboolean remote_arguments;
char **env;
char *startup_id;
char *display_name;
int screen_number;
GList *initial_windows;
gboolean default_window_menubar_forced;
gboolean default_window_menubar_state;
gboolean default_fullscreen;
gboolean default_maximize;
char *default_role;
char *default_geometry;
char *default_working_dir;
char *default_title;
char **exec_argv;
char *default_profile;
gboolean default_profile_is_id;
gboolean remote_arguments;
char **env;
char *startup_id;
char *display_name;
int screen_number;
GList *initial_windows;
gboolean default_window_menubar_forced;
gboolean default_window_menubar_state;
gboolean default_fullscreen;
gboolean default_maximize;
char *default_role;
char *default_geometry;
char *default_working_dir;
char *default_title;
char **exec_argv;
char *default_profile;
gboolean default_profile_is_id;
gboolean execute;
gboolean use_factory;
double zoom;
gboolean execute;
gboolean use_factory;
double zoom;
char *config_file;
gboolean load_config;
gboolean save_config;
char *config_file;
gboolean load_config;
gboolean save_config;
} TerminalOptions;
typedef struct
{
char *profile;
gboolean profile_is_id;
char **exec_argv;
char *title;
char *working_dir;
double zoom;
guint zoom_set : 1;
guint active : 1;
char *profile;
gboolean profile_is_id;
char **exec_argv;
char *title;
char *working_dir;
double zoom;
guint zoom_set : 1;
guint active : 1;
} InitialTab;
typedef struct
{
guint source_tag;
guint source_tag;
GList *tabs; /* list of InitialTab */
GList *tabs; /* list of InitialTab */
gboolean force_menubar_state;
gboolean menubar_state;
gboolean force_menubar_state;
gboolean menubar_state;
gboolean start_fullscreen;
gboolean start_maximized;
gboolean start_fullscreen;
gboolean start_maximized;
char *geometry;
char *role;
char *geometry;
char *role;
} InitialWindow;
#define TERMINAL_OPTION_ERROR (g_quark_from_static_string ("terminal-option-error"))
typedef enum {
TERMINAL_OPTION_ERROR_NOT_IN_FACTORY,
TERMINAL_OPTION_ERROR_EXCLUSIVE_OPTIONS,
TERMINAL_OPTION_ERROR_INVALID_CONFIG_FILE,
TERMINAL_OPTION_ERROR_INCOMPATIBLE_CONFIG_FILE
typedef enum
{
TERMINAL_OPTION_ERROR_NOT_IN_FACTORY,
TERMINAL_OPTION_ERROR_EXCLUSIVE_OPTIONS,
TERMINAL_OPTION_ERROR_INVALID_CONFIG_FILE,
TERMINAL_OPTION_ERROR_INCOMPATIBLE_CONFIG_FILE
} TerminalOptionError;
TerminalOptions *terminal_options_parse (const char *working_directory,
const char *display_name,
const char *startup_id,
char **env,
gboolean remote_arguments,
gboolean ignore_unknown_options,
int *argcp,
char ***argvp,
GError **error,
...) G_GNUC_NULL_TERMINATED;
const char *display_name,
const char *startup_id,
char **env,
gboolean remote_arguments,
gboolean ignore_unknown_options,
int *argcp,
char ***argvp,
GError **error,
...) G_GNUC_NULL_TERMINATED;
gboolean terminal_options_merge_config (TerminalOptions *options,
GKeyFile *key_file,

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -38,15 +38,15 @@ typedef struct _TerminalScreenContainerPrivate TerminalScreenContainerPrivate;
struct _TerminalScreenContainer
{
GtkVBox parent_instance;
GtkVBox parent_instance;
/*< private >*/
TerminalScreenContainerPrivate *priv;
/*< private >*/
TerminalScreenContainerPrivate *priv;
};
struct _TerminalScreenContainerClass
{
GtkVBoxClass parent_class;
GtkVBoxClass parent_class;
};
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);
void terminal_screen_container_set_policy (TerminalScreenContainer *container,
GtkPolicyType hpolicy,
GtkPolicyType vpolicy);
GtkPolicyType hpolicy,
GtkPolicyType vpolicy);
void terminal_screen_container_set_placement (TerminalScreenContainer *container,
GtkCornerType corner);
GtkCornerType corner);
G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@ -27,12 +27,13 @@
G_BEGIN_DECLS
typedef enum {
FLAVOR_AS_IS,
FLAVOR_DEFAULT_TO_HTTP,
FLAVOR_VOIP_CALL,
FLAVOR_EMAIL,
FLAVOR_SKEY
typedef enum
{
FLAVOR_AS_IS,
FLAVOR_DEFAULT_TO_HTTP,
FLAVOR_VOIP_CALL,
FLAVOR_EMAIL,
FLAVOR_SKEY
} TerminalURLFlavour;
/* Forward decls */
@ -52,24 +53,24 @@ typedef struct _TerminalScreenPrivate TerminalScreenPrivate;
struct _TerminalScreen
{
VteTerminal parent_instance;
VteTerminal parent_instance;
TerminalScreenPrivate *priv;
TerminalScreenPrivate *priv;
};
struct _TerminalScreenClass
{
VteTerminalClass parent_class;
VteTerminalClass parent_class;
void (* profile_set) (TerminalScreen *screen,
TerminalProfile *old_profile);
void (* show_popup_menu) (TerminalScreen *screen,
TerminalScreenPopupInfo *info);
gboolean (* match_clicked) (TerminalScreen *screen,
const char *url,
int flavour,
guint state);
void (* close_screen) (TerminalScreen *screen);
void (* profile_set) (TerminalScreen *screen,
TerminalProfile *old_profile);
void (* show_popup_menu) (TerminalScreen *screen,
TerminalScreenPopupInfo *info);
gboolean (* match_clicked) (TerminalScreen *screen,
const char *url,
int flavour,
guint state);
void (* close_screen) (TerminalScreen *screen);
};
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);
void terminal_screen_set_override_command (TerminalScreen *screen,
char **argv);
char **argv);
const char** terminal_screen_get_override_command (TerminalScreen *screen);
void terminal_screen_set_initial_environment (TerminalScreen *screen,
char **argv);
char **argv);
char ** terminal_screen_get_initial_environment (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);
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_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_scale (TerminalScreen *screen,
double factor);
double factor);
double terminal_screen_get_font_scale (TerminalScreen *screen);
void terminal_screen_get_size (TerminalScreen *screen,
int *width_chars,
int *height_chars);
void terminal_screen_get_cell_size (TerminalScreen *screen,
int *width_chars,
int *height_chars);
int *width_chars,
int *height_chars);
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_MAXIMUM (TERMINAL_SCALE_XXXXX_LARGE*1.2)
struct _TerminalScreenPopupInfo {
int ref_count;
TerminalWindow *window;
TerminalScreen *screen;
char *string;
TerminalURLFlavour flavour;
guint button;
guint state;
guint32 timestamp;
struct _TerminalScreenPopupInfo
{
int ref_count;
TerminalWindow *window;
TerminalScreen *screen;
char *string;
TerminalURLFlavour flavour;
guint button;
guint state;
guint32 timestamp;
};
TerminalScreenPopupInfo *terminal_screen_popup_info_ref (TerminalScreenPopupInfo *info);

View File

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

View File

@ -25,9 +25,10 @@
G_BEGIN_DECLS
typedef enum _TerminalSearchFlags {
TERMINAL_SEARCH_FLAG_BACKWARDS = 1 << 0,
TERMINAL_SEARCH_FLAG_WRAP_AROUND = 1 << 1
typedef enum _TerminalSearchFlags
{
TERMINAL_SEARCH_FLAG_BACKWARDS = 1 << 0,
TERMINAL_SEARCH_FLAG_WRAP_AROUND = 1 << 1
} TerminalSearchFlags;
@ -36,12 +37,12 @@ GtkWidget *terminal_search_dialog_new (GtkWindow *parent);
void terminal_search_dialog_present (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);
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);
G_END_DECLS

View File

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

View File

@ -38,18 +38,18 @@ typedef struct _TerminalTabLabelPrivate TerminalTabLabelPrivate;
struct _TerminalTabLabel
{
GtkHBox parent_instance;
GtkHBox parent_instance;
/*< private >*/
TerminalTabLabelPrivate *priv;
/*< private >*/
TerminalTabLabelPrivate *priv;
};
struct _TerminalTabLabelClass
{
GtkHBoxClass parent_class;
GtkHBoxClass parent_class;
/* Signals */
void (* close_button_clicked) (TerminalTabLabel *tab_label);
/* Signals */
void (* close_button_clicked) (TerminalTabLabel *tab_label);
};
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);
void terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
gboolean bold);
gboolean bold);
G_END_DECLS

View File

@ -56,8 +56,8 @@ struct _TerminalTabsMenuPrivate
enum
{
PROP_0,
PROP_WINDOW
PROP_0,
PROP_WINDOW
};
static void terminal_tabs_menu_update (TerminalTabsMenu *menu);
@ -76,77 +76,77 @@ G_DEFINE_TYPE (TerminalTabsMenu, terminal_tabs_menu, G_TYPE_OBJECT)
static guint
allocate_tab_id (void)
{
int bit;
guint b, len;
guint8 *data;
guint8 byte, mask;
int bit;
guint b, len;
guint8 *data;
guint8 byte, mask;
if (n_tabs++ == 0)
{
g_assert (tabs_id_array == NULL);
tabs_id_array = g_byte_array_sized_new (16);
}
if (n_tabs++ == 0)
{
g_assert (tabs_id_array == NULL);
tabs_id_array = g_byte_array_sized_new (16);
}
/* Find a free ID */
len = tabs_id_array->len;
data = tabs_id_array->data;
for (b = 0; b < len; ++b)
{
if (data[b] != 0xff)
break;
}
/* Find a free ID */
len = tabs_id_array->len;
data = tabs_id_array->data;
for (b = 0; b < len; ++b)
{
if (data[b] != 0xff)
break;
}
/* Need to append a new byte */
if (b == len)
{
guint8 bytes[] = { 0 };
g_byte_array_append (tabs_id_array, bytes, G_N_ELEMENTS (bytes));
g_assert (tabs_id_array->len > b);
}
/* Need to append a new byte */
if (b == len)
{
guint8 bytes[] = { 0 };
g_byte_array_append (tabs_id_array, bytes, G_N_ELEMENTS (bytes));
g_assert (tabs_id_array->len > b);
}
data = tabs_id_array->data + b;
byte = 0xff ^ *data;
/* Now find the first free bit */
bit = g_bit_nth_lsf (byte, -1);
mask = 1 << bit;
g_assert (bit >= 0 && bit <= 7);
g_assert ((*data & mask) == 0);
/* And mark it as allocated */
*data |= mask;
data = tabs_id_array->data + b;
byte = 0xff ^ *data;
/* Now find the first free bit */
bit = g_bit_nth_lsf (byte, -1);
mask = 1 << bit;
g_assert (bit >= 0 && bit <= 7);
g_assert ((*data & mask) == 0);
/* And mark it as allocated */
*data |= mask;
return b * 8 + bit;
return b * 8 + bit;
}
static void
free_tab_id (GtkAction *action)
{
const char *name;
guint id;
guint8 *data;
guint b, bit;
const char *name;
guint id;
guint8 *data;
guint b, bit;
name = gtk_action_get_name (action);
id = g_ascii_strtoull (name + ACTION_VERB_FORMAT_PREFIX_LEN, NULL,
ACTION_VERB_FORMAT_BASE);
g_assert (id < tabs_id_array->len * 8);
name = gtk_action_get_name (action);
id = g_ascii_strtoull (name + ACTION_VERB_FORMAT_PREFIX_LEN, NULL,
ACTION_VERB_FORMAT_BASE);
g_assert (id < tabs_id_array->len * 8);
b = id >> 3;
bit = id & 0x7;
data = tabs_id_array->data + b;
*data &= ~(1 << bit);
b = id >> 3;
bit = id & 0x7;
data = tabs_id_array->data + b;
*data &= ~(1 << bit);
g_assert (n_tabs > 0);
if (--n_tabs == 0)
{
g_assert (tabs_id_array != NULL);
g_byte_array_free (tabs_id_array, TRUE);
tabs_id_array = NULL;
}
g_assert (n_tabs > 0);
if (--n_tabs == 0)
{
g_assert (tabs_id_array != NULL);
g_byte_array_free (tabs_id_array, TRUE);
tabs_id_array = NULL;
}
}
static void
tab_action_activate_cb (GtkToggleAction *action,
TerminalTabsMenu *menu)
TerminalTabsMenu *menu)
{
TerminalTabsMenuPrivate *priv = menu->priv;
TerminalScreen *screen;
@ -161,14 +161,14 @@ tab_action_activate_cb (GtkToggleAction *action,
if (terminal_window_get_active (priv->window) != screen)
{
terminal_window_switch_screen (priv->window, screen);
terminal_window_switch_screen (priv->window, screen);
}
}
static void
sync_tab_title (TerminalScreen *screen,
GParamSpec *pspec,
GtkAction *action)
GParamSpec *pspec,
GtkAction *action)
{
const char *title;
@ -180,28 +180,28 @@ sync_tab_title (TerminalScreen *screen,
static void
notebook_page_added_cb (GtkNotebook *notebook,
TerminalScreenContainer *container,
guint position,
TerminalTabsMenu *menu)
guint position,
TerminalTabsMenu *menu)
{
TerminalTabsMenuPrivate *priv = menu->priv;
GtkAction *action;
char verb[ACTION_VERB_FORMAT_LENGTH];
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 ());
action = g_object_new (GTK_TYPE_RADIO_ACTION,
"name", verb,
"tooltip", _("Switch to this tab"),
NULL);
"name", verb,
"tooltip", _("Switch to this tab"),
NULL);
sync_tab_title (screen, NULL, action);
/* make sure the action is alive when handling the signal, see bug #169833 */
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);
@ -218,7 +218,7 @@ notebook_page_added_cb (GtkNotebook *notebook,
g_object_set_data (G_OBJECT (action), DATA_KEY, screen);
g_signal_connect (action, "activate",
G_CALLBACK (tab_action_activate_cb), menu);
G_CALLBACK (tab_action_activate_cb), menu);
g_object_unref (action);
@ -228,37 +228,37 @@ notebook_page_added_cb (GtkNotebook *notebook,
static void
notebook_page_removed_cb (GtkNotebook *notebook,
TerminalScreenContainer *container,
guint position,
TerminalTabsMenu *menu)
guint position,
TerminalTabsMenu *menu)
{
TerminalTabsMenuPrivate *priv = menu->priv;
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);
g_return_if_fail (action != NULL);
free_tab_id (action);
free_tab_id (action);
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
(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);
gtk_action_group_remove_action (priv->action_group, action);
gtk_action_group_remove_action (priv->action_group, action);
terminal_tabs_menu_update (menu);
}
static void
notebook_page_reordered_cb (GtkNotebook *notebook,
GtkBin *bin,
guint position,
TerminalTabsMenu *menu)
GtkBin *bin,
guint position,
TerminalTabsMenu *menu)
{
terminal_tabs_menu_update (menu);
}
@ -273,28 +273,28 @@ notebook_page_switch_cb (GtkNotebook *notebook,
guint position,
TerminalTabsMenu *menu)
{
TerminalScreenContainer *container;
TerminalScreen *screen;
GtkAction *action;
TerminalScreenContainer *container;
TerminalScreen *screen;
GtkAction *action;
#if GTK_CHECK_VERSION (2, 90, 6)
container = TERMINAL_SCREEN_CONTAINER (page);
container = TERMINAL_SCREEN_CONTAINER (page);
#else
container = TERMINAL_SCREEN_CONTAINER (gtk_notebook_get_nth_page (notebook, position));
container = TERMINAL_SCREEN_CONTAINER (gtk_notebook_get_nth_page (notebook, position));
#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);
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);
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
connect_proxy_cb (GtkActionGroup *action_group,
GtkAction *action,
GtkWidget *proxy,
gpointer dummy)
GtkAction *action,
GtkWidget *proxy,
gpointer dummy)
{
if (GTK_IS_MENU_ITEM (proxy))
{
@ -310,7 +310,7 @@ connect_proxy_cb (GtkActionGroup *action_group,
static void
terminal_tabs_menu_set_window (TerminalTabsMenu *menu,
TerminalWindow *window)
TerminalWindow *window)
{
TerminalTabsMenuPrivate *priv = menu->priv;
GtkWidget *notebook;
@ -324,49 +324,49 @@ terminal_tabs_menu_set_window (TerminalTabsMenu *menu,
g_object_unref (priv->action_group);
priv->anchor_action = g_object_new (GTK_TYPE_RADIO_ACTION,
"name", "TabsMenuAnchorAction",
NULL);
"name", "TabsMenuAnchorAction",
NULL);
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_CALLBACK (connect_proxy_cb), NULL);
G_CALLBACK (connect_proxy_cb), NULL);
notebook = terminal_window_get_notebook (window);
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_CALLBACK (notebook_page_removed_cb), menu, 0);
G_CALLBACK (notebook_page_removed_cb), menu, 0);
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_CALLBACK (notebook_page_switch_cb), menu, 0);
G_CALLBACK (notebook_page_switch_cb), menu, 0);
}
static void
terminal_tabs_menu_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TerminalTabsMenu *menu = TERMINAL_TABS_MENU (object);
switch (prop_id)
{
case PROP_WINDOW:
terminal_tabs_menu_set_window (menu, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_WINDOW:
terminal_tabs_menu_set_window (menu, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
terminal_tabs_menu_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
/* no readable properties */
g_return_if_reached ();
@ -381,16 +381,16 @@ terminal_tabs_menu_class_init (TerminalTabsMenuClass *klass)
object_class->get_property = terminal_tabs_menu_get_property;
g_object_class_install_property (object_class,
PROP_WINDOW,
g_param_spec_object ("window", NULL, NULL,
TERMINAL_TYPE_WINDOW,
G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
G_PARAM_CONSTRUCT_ONLY));
PROP_WINDOW,
g_param_spec_object ("window", NULL, NULL,
TERMINAL_TYPE_WINDOW,
G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (object_class, sizeof (TerminalTabsMenuPrivate));
/* We don't want to save accels, so skip them */
gtk_accel_map_add_filter ("<Actions>/Main/TabsSwitch*");
/* We don't want to save accels, so skip them */
gtk_accel_map_add_filter ("<Actions>/Main/TabsSwitch*");
}
static void
@ -417,29 +417,29 @@ TerminalTabsMenu *
terminal_tabs_menu_new (TerminalWindow *window)
{
return TERMINAL_TABS_MENU (g_object_new (TERMINAL_TYPE_TABS_MENU,
"window", window,
NULL));
"window", window,
NULL));
}
static void
tab_set_action_accelerator (GtkActionGroup *action_group,
GtkAction *action,
guint tab_number,
gboolean is_single_tab)
GtkAction *action,
guint tab_number,
gboolean is_single_tab)
{
if (!is_single_tab &&
tab_number < TERMINAL_ACCELS_N_TABS_SWITCH)
{
char accel_path[ACCEL_PATH_FORMAT_LENGTH];
if (!is_single_tab &&
tab_number < TERMINAL_ACCELS_N_TABS_SWITCH)
{
char accel_path[ACCEL_PATH_FORMAT_LENGTH];
g_snprintf (accel_path, sizeof (accel_path), ACCEL_PATH_FORMAT, tab_number + 1);
gtk_action_set_accel_path (action, accel_path);
}
else
{
gtk_action_set_accel_path (action, NULL);
return;
}
g_snprintf (accel_path, sizeof (accel_path), ACCEL_PATH_FORMAT, tab_number + 1);
gtk_action_set_accel_path (action, accel_path);
}
else
{
gtk_action_set_accel_path (action, NULL);
return;
}
}
static void
@ -467,20 +467,20 @@ terminal_tabs_menu_update (TerminalTabsMenu *menu)
for (l = tabs; l != NULL; l = l->next)
{
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (l->data);
GObject *screen = G_OBJECT (terminal_screen_container_get_screen (container));
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (l->data);
GObject *screen = G_OBJECT (terminal_screen_container_get_screen (container));
action = g_object_get_data (screen, DATA_KEY);
g_return_if_fail (action != NULL);
verb = gtk_action_get_name (action);
tab_set_action_accelerator (p->action_group, action, i++, is_single_tab);
gtk_ui_manager_add_ui (manager, p->ui_id,
UI_PATH,
verb, verb,
GTK_UI_MANAGER_MENUITEM, FALSE);
UI_PATH,
verb, verb,
GTK_UI_MANAGER_MENUITEM, FALSE);
}
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_show_error_dialog (GtkWindow *transient_parent,
GtkWidget **weap_ptr,
void terminal_util_show_error_dialog (GtkWindow *transient_parent,
GtkWidget **weap_ptr,
GError *error,
const char *message_format, ...) G_GNUC_PRINTF(4, 5);
void terminal_util_show_help (const char *topic, GtkWindow *transient_parent);
void terminal_util_set_labelled_by (GtkWidget *widget,
GtkLabel *label);
GtkLabel *label);
void terminal_util_set_atk_name_description (GtkWidget *widget,
const char *name,
const char *desc);
const char *name,
const char *desc);
void terminal_util_open_url (GtkWidget *parent,
const char *orig_url,
@ -52,7 +52,7 @@ void terminal_util_open_url (GtkWidget *parent,
guint32 user_time);
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);
@ -62,46 +62,47 @@ char *terminal_util_concat_uris (char **uris,
char *terminal_util_get_licence_text (void);
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);
void terminal_util_key_file_set_string_escape (GKeyFile *key_file,
const char *group,
const char *key,
const char *string);
const char *group,
const char *key,
const char *string);
char *terminal_util_key_file_get_string_unescape (GKeyFile *key_file,
const char *group,
const char *key,
GError **error);
const char *group,
const char *key,
GError **error);
void terminal_util_key_file_set_argv (GKeyFile *key_file,
const char *group,
const char *key,
int argc,
char **argv);
const char *group,
const char *key,
int argc,
char **argv);
char **terminal_util_key_file_get_argv (GKeyFile *key_file,
const char *group,
const char *key,
int *argc,
GError **error);
const char *group,
const char *key,
int *argc,
GError **error);
void terminal_util_add_proxy_env (GHashTable *env_table);
typedef enum {
FLAG_INVERT_BOOL = 1 << 0,
typedef enum
{
FLAG_INVERT_BOOL = 1 << 0,
} PropertyChangeFlags;
void terminal_util_bind_object_property_to_widget (GObject *object,
const char *object_prop,
GtkWidget *widget,
PropertyChangeFlags flags);
const char *object_prop,
GtkWidget *widget,
PropertyChangeFlags flags);
gboolean terminal_util_x11_get_net_wm_desktop (GdkWindow *window,
guint32 *desktop);
guint32 *desktop);
void terminal_util_x11_set_net_wm_desktop (GdkWindow *window,
guint32 desktop);
guint32 desktop);
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
{
GtkWindow parent_instance;
GtkWindow parent_instance;
TerminalWindowPrivate *priv;
TerminalWindowPrivate *priv;
};
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
*/
void terminal_window_set_menubar_visible (TerminalWindow *window,
gboolean setting);
gboolean setting);
gboolean terminal_window_get_menubar_visible (TerminalWindow *window);
void terminal_window_switch_screen (TerminalWindow *window,
TerminalScreen *screen);
TerminalScreen *screen);
TerminalScreen* terminal_window_get_active (TerminalWindow *window);
GList* terminal_window_list_screen_containers (TerminalWindow *window);
@ -88,10 +88,10 @@ void terminal_window_set_size (TerminalWindow *window,
TerminalScreen *screen,
gboolean even_if_mapped);
void terminal_window_set_size_force_grid (TerminalWindow *window,
TerminalScreen *screen,
gboolean even_if_mapped,
int force_grid_width,
int force_grid_height);
TerminalScreen *screen,
gboolean even_if_mapped,
int force_grid_width,
int force_grid_height);
GtkWidget* terminal_window_get_notebook (TerminalWindow *window);

View File

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