- Added GTK+-based clipboard support for Linux.

- Fixed: Most Linux filesystems do not fill in d_type for scandir(), so we
  cannot rely on it to detect directories.
- Added NicePath() function to perform shell-style ~ substitution on path
  names.
- Changed the default screenshot directory on Unix to ~/.zdoom/screenshots/.
- Added -shotdir command line option to temporarily override the
  screenshot_dir cvar.



SVN r1413 (trunk)
This commit is contained in:
Randy Heit 2009-02-08 02:52:43 +00:00
parent 125be6b54e
commit be165578ea
7 changed files with 199 additions and 69 deletions

View file

@ -1,3 +1,13 @@
February 7, 2009
- Added GTK+-based clipboard support for Linux.
- Fixed: Most Linux filesystems do not fill in d_type for scandir(), so we
cannot rely on it to detect directories.
- Added NicePath() function to perform shell-style ~ substitution on path
names.
- Changed the default screenshot directory on Unix to ~/.zdoom/screenshots/.
- Added -shotdir command line option to temporarily override the
screenshot_dir cvar.
February 7, 2009 (Changes by Graf Zahl) February 7, 2009 (Changes by Graf Zahl)
- Fixed: G_SerializeLevel must use the TEXMAN_ReturnFirst flag for getting - Fixed: G_SerializeLevel must use the TEXMAN_ReturnFirst flag for getting
the sky textures so that it still works when the first texture in a TEXTURE1 the sky textures so that it still works when the first texture in a TEXTURE1

View file

@ -505,7 +505,7 @@ CCMD (error_fatal)
CCMD (dir) CCMD (dir)
{ {
FString dir; FString dir, path;
char curdir[256]; char curdir[256];
const char *match; const char *match;
findstate_t c_file; findstate_t c_file;
@ -517,38 +517,45 @@ CCMD (dir)
return; return;
} }
if (argv.argc() == 1 || chdir (argv[1])) if (argv.argc() > 1)
{ {
match = argv.argc() == 1 ? "./*" : argv[1]; path = NicePath(argv[1]);
if (chdir(path))
dir = ExtractFilePath (match);
if (dir[0] != '\0')
{ {
match += dir.Len(); match = path;
dir = ExtractFilePath(path);
if (dir[0] != '\0')
{
match += dir.Len();
}
else
{
dir = "./";
}
if (match[0] == '\0')
{
match = "*";
}
if (chdir (dir))
{
Printf ("%s not found\n", dir.GetChars());
return;
}
} }
else else
{
dir = "./";
}
if (match[0] == '\0')
{ {
match = "*"; match = "*";
} dir = path;
if (chdir (dir))
{
Printf ("%s not found\n", dir.GetChars());
return;
} }
} }
else else
{ {
match = "*"; match = "*";
dir = argv[1]; dir = curdir;
if (dir[dir.Len()-1] != '/') }
{ if (dir[dir.Len()-1] != '/')
dir += '/'; {
} dir += '/';
} }
if ( (file = I_FindFirst (match, &c_file)) == ((void *)(-1))) if ( (file = I_FindFirst (match, &c_file)) == ((void *)(-1)))

View file

@ -2,6 +2,10 @@
#ifdef _WIN32 #ifdef _WIN32
#include <direct.h> #include <direct.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#endif #endif
#include "doomtype.h" #include "doomtype.h"
#include "cmdlib.h" #include "cmdlib.h"
@ -345,25 +349,20 @@ const char *myasctime ()
/* CreatePath: creates a directory including all levels necessary */ /* CreatePath: creates a directory including all levels necessary */
/* */ /* */
/************************************************************************/ /************************************************************************/
#ifdef _WIN32
void DoCreatePath(const char * fn) void DoCreatePath(const char * fn)
{ {
#ifdef _WIN32 char drive[_MAX_DRIVE];
char drive[_MAX_DRIVE]; char path[PATH_MAX];
#endif char p[PATH_MAX];
char path[PATH_MAX]; int i;
char p[PATH_MAX];
int i;
#ifdef _WIN32
_splitpath(fn,drive,path,NULL,NULL); _splitpath(fn,drive,path,NULL,NULL);
_makepath(p,drive,path,NULL,NULL); _makepath(p,drive,path,NULL,NULL);
i=(int)strlen(p); i=(int)strlen(p);
if (p[i-1]=='/' || p[i-1]=='\\') p[i-1]=0; if (p[i-1]=='/' || p[i-1]=='\\') p[i-1]=0;
if (*path) DoCreatePath(p); if (*path) DoCreatePath(p);
_mkdir(p); _mkdir(p);
#else
// FIXME: write me
#endif
} }
void CreatePath(const char * fn) void CreatePath(const char * fn)
@ -378,6 +377,36 @@ void CreatePath(const char * fn)
} }
else DoCreatePath(fn); else DoCreatePath(fn);
} }
#else
void CreatePath(const char *fn)
{
char *copy, *p;
if (fn[0] == '/' && fn[1] == '\0')
{
return;
}
p = copy = strdup(fn);
do
{
p = strchr(p + 1, '/');
if (p != NULL)
{
*p = '\0';
}
printf("%s\n", copy);
if (mkdir(copy, 0755) == -1)
{ // failed
return;
}
if (p != NULL)
{
*p = '/';
}
} while (p);
free(copy);
}
#endif
// [RH] Replaces the escape sequences in a string with actual escaped characters. // [RH] Replaces the escape sequences in a string with actual escaped characters.
// This operation is done in-place. The result is the new length of the string. // This operation is done in-place. The result is the new length of the string.
@ -626,3 +655,56 @@ FString ExpandEnvVars(const char *searchpathstring)
return out; return out;
} }
//==========================================================================
//
// NicePath
//
// Handles paths with leading ~ characters on Unix as well as environment
// variable substitution. On Windows, this is identical to ExpandEnvVars.
//
//==========================================================================
FString NicePath(const char *path)
{
#ifdef _WIN32
return ExpandEnvVars(path);
#else
if (path == NULL || *path == '\0')
{
return FString("");
}
if (*path != '~')
{
return ExpandEnvVars(path);
}
passwd *pwstruct;
const char *slash;
if (path[1] == '/' || path[1] == '\0')
{ // Get my home directory
pwstruct = getpwuid(getuid());
slash = path + 1;
}
else
{ // Get somebody else's home directory
slash = strchr(path, '/');
if (slash == NULL)
{
slash = path + strlen(path);
}
FString who(path, slash - path);
pwstruct = getpwnam(who);
}
if (pwstruct == NULL)
{
return ExpandEnvVars(path);
}
FString where(pwstruct->pw_dir);
if (*slash != '\0')
{
where += ExpandEnvVars(slash);
}
return where;
#endif
}

View file

@ -57,5 +57,6 @@ FString strbin1 (const char *start);
void CreatePath(const char * fn); void CreatePath(const char * fn);
FString ExpandEnvVars(const char *searchpathstring); FString ExpandEnvVars(const char *searchpathstring);
FString NicePath(const char *path);
#endif #endif

View file

@ -2263,20 +2263,12 @@ void D_DoomMain (void)
#endif #endif
file += "skins"; file += "skins";
D_AddDirectory (file); D_AddDirectory (file);
const char *home = getenv ("HOME"); #ifdef unix
if (home) file = NicePath("~/" GAME_DIR "/skins");
{ D_AddDirectory (file);
file = home; #endif
if (home[strlen(home) - 1] != '/')
{
file += '/';
}
file += ".zdoom/skins";
D_AddDirectory (file);
}
// Add common (global) wads // Add common (global) wads
D_AddConfigWads ("Global.Autoload"); D_AddConfigWads ("Global.Autoload");

View file

@ -301,19 +301,17 @@ static long ParseCommandLine (const char *args, int *argc, char **argv)
#ifdef unix #ifdef unix
FString GetUserFile (const char *file, bool nodir) FString GetUserFile (const char *file, bool nodir)
{ {
char *home = getenv ("HOME"); FString path;
if (home == NULL || *home == '\0')
I_FatalError ("Please set your HOME environment variable");
FString path = home; if (nodir)
if (path[path.Len()-1] != '/') {
path += nodir ? "/" : "/"GAME_DIR; path = NicePath("~/");
else if (!nodir) }
path += GAME_DIR; else
if (!nodir)
{ {
struct stat info; struct stat info;
path = NicePath("~/" GAME_DIR "/");
if (stat (path, &info) == -1) if (stat (path, &info) == -1)
{ {
if (mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1) if (mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
@ -330,7 +328,6 @@ FString GetUserFile (const char *file, bool nodir)
} }
} }
} }
path += '/';
path += file; path += file;
return path; return path;
} }
@ -649,10 +646,20 @@ void M_ScreenShot (const char *filename)
else else
#endif #endif
{ {
int dirlen = (int)strlen (screenshot_dir); int dirlen;
autoname = Args->CheckValue("-shotdir");
if (autoname == NULL)
{
autoname = screenshot_dir;
}
dirlen = strlen(autoname);
if (dirlen == 0) if (dirlen == 0)
{ {
#ifdef unix
autoname = "~/.zdoom/screenshots/";
#else
autoname = progdir; autoname = progdir;
#endif
} }
else if (dirlen > 0) else if (dirlen > 0)
{ {
@ -663,6 +670,7 @@ void M_ScreenShot (const char *filename)
} }
} }
} }
autoname = NicePath(autoname);
if (!FindFreeName (autoname, writepcx ? "pcx" : "png")) if (!FindFreeName (autoname, writepcx ? "pcx" : "png"))
{ {
Printf ("M_ScreenShot: Delete some screenshots\n"); Printf ("M_ScreenShot: Delete some screenshots\n");

View file

@ -30,6 +30,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h>
#ifndef NO_GTK #ifndef NO_GTK
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h> #include <gdk/gdkkeysyms.h>
@ -509,11 +510,7 @@ bool I_WriteIniFailed ()
static const char *pattern; static const char *pattern;
#ifdef OSF1
static int matchfile (struct dirent *ent)
#else
static int matchfile (const struct dirent *ent) static int matchfile (const struct dirent *ent)
#endif
{ {
return fnmatch (pattern, ent->d_name, FNM_NOESCAPE) == 0; return fnmatch (pattern, ent->d_name, FNM_NOESCAPE) == 0;
} }
@ -568,21 +565,54 @@ int I_FindClose (void *handle)
int I_FindAttr (findstate_t *fileinfo) int I_FindAttr (findstate_t *fileinfo)
{ {
struct dirent *ent = fileinfo->namelist[fileinfo->current]; dirent *ent = fileinfo->namelist[fileinfo->current];
struct stat buf;
#ifdef OSF1 if (stat(ent->d_name, &buf) == 0)
return 0; // I don't know how to detect dirs under OSF/1 {
#else return S_ISDIR(buf.st_mode) ? FA_DIREC : 0;
return (ent->d_type == DT_DIR) ? FA_DIREC : 0; }
#endif return 0;
} }
// No clipboard support for Linux // Clipboard support requires GTK+
// TODO: GTK+ uses UTF-8. We don't, so some conversions would be appropriate.
void I_PutInClipboard (const char *str) void I_PutInClipboard (const char *str)
{ {
#ifndef NO_GTK
if (GtkAvailable)
{
GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
if (clipboard != NULL)
{
gtk_clipboard_set_text(clipboard, str, -1);
}
clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
if (clipboard != NULL)
{
gtk_clipboard_set_text(clipboard, str, -1);
}
}
#endif
} }
char *I_GetFromClipboard () char *I_GetFromClipboard ()
{ {
#ifndef NO_GTK
if (GtkAvailable)
{
GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
if (clipboard != NULL)
{
gchar *text = gtk_clipboard_wait_for_text(clipboard);
if (text != NULL)
{
char *copy = copystring(text);
g_free(text);
return copy;
}
}
}
#endif
return NULL; return NULL;
} }