Merge pull request #360 from pryon/UINotepad-fixes

UINotepad fixes and improvements
This commit is contained in:
smallmodel 2024-09-22 19:35:52 +02:00 committed by GitHub
commit 1fd6c2bd52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 486 additions and 335 deletions

View file

@ -24,6 +24,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../win_localization.h"
#include "../sys_loadlib.h"
// a pointer to the last piece of data retrieved from the clipboard is stored here,
// so that it can be cleaned up when new data is retrieved, preventing memory leaks
static void* clipboard_text = NULL;
static void* game_library = NULL;
static void* cgame_library = NULL;
qboolean GLimp_SpawnRenderThread(void (*function)(void))
@ -134,7 +138,36 @@ Sys_GetWholeClipboard
*/
const char* Sys_GetWholeClipboard(void)
{
#ifndef DEDICATED
char *data = NULL;
char *cliptext;
if ((cliptext = SDL_GetClipboardText()) != NULL) {
if (cliptext[0] != NULL) {
// It's necessary to limit buffersize to 4096 as each character
// is pasted via CharEvent, which is very-very slow and jams up the EventQueue.
// A smaller buffer doesn't jam the EventQueue up as much and avoids dropping
// characters that otherwise happens when the EventQueue is overloaded.
// FIXME: speed up paste logic so this restriction can be removed
size_t bufsize = Q_min(strlen(cliptext) + 1, 4096);
if (clipboard_text != NULL) {
// clean up previously allocated clipboard buffer
Z_Free(clipboard_text);
clipboard_text = NULL;
}
data = clipboard_text = Z_Malloc(bufsize);
// Changed in OPM:
// original game skips the Windows-specific '\r' (carriage return) char here!
Q_strncpyz(data, cliptext, bufsize);
}
SDL_free(cliptext);
}
return data;
#else
return NULL;
#endif
}
/*
@ -142,8 +175,15 @@ const char* Sys_GetWholeClipboard(void)
Sys_SetClipboard
==============
*/
void Sys_SetClipboard(const char* contents)
void Sys_SetClipboard(const char *contents)
{
#ifndef DEDICATED
if (contents == NULL || contents[0] == NULL) {
return;
}
SDL_SetClipboardText(contents);
#endif
}
/*

View file

@ -146,26 +146,8 @@ Sys_GetClipboardData
*/
char *Sys_GetClipboardData(void)
{
#ifdef DEDICATED
return NULL;
#else
char *data = NULL;
char *cliptext;
if ( ( cliptext = SDL_GetClipboardText() ) != NULL ) {
if ( cliptext[0] != '\0' ) {
size_t bufsize = strlen( cliptext ) + 1;
data = Z_Malloc( bufsize );
Q_strncpyz( data, cliptext, bufsize );
// find first listed char and set to '\0'
strtok( data, "\n\r\b" );
}
SDL_free( cliptext );
}
return data;
#endif
// unused - actual function is implemented in sys_main_new.c
return NULL;
}
#ifdef DEDICATED

View file

@ -369,60 +369,76 @@ DIRECTORY SCANNING
Sys_ListFilteredFiles
==================
*/
void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **list, int *numfiles )
void Sys_ListFilteredFiles(
const char *basedir, char *subdirs, char *filter, qboolean wantsubs, char **list, int *numfiles
)
{
char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
char filename[MAX_OSPATH];
DIR *fdir;
struct dirent *d;
struct stat st;
char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
char filename[MAX_OSPATH];
DIR *fdir;
struct dirent *d;
struct stat st;
if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
return;
}
if (*numfiles >= MAX_FOUND_FILES - 1) {
return;
}
if ( basedir[0] == '\0' ) {
return;
}
if (basedir[0] == '\0') {
return;
}
if (strlen(subdirs)) {
Com_sprintf( search, sizeof(search), "%s/%s", basedir, subdirs );
}
else {
Com_sprintf( search, sizeof(search), "%s", basedir );
}
if (strlen(subdirs)) {
Com_sprintf(search, sizeof(search), "%s/%s", basedir, subdirs);
} else {
Com_sprintf(search, sizeof(search), "%s", basedir);
}
if ((fdir = opendir(search)) == NULL) {
return;
}
if ((fdir = opendir(search)) == NULL) {
return;
}
while ((d = readdir(fdir)) != NULL) {
Com_sprintf(filename, sizeof(filename), "%s/%s", search, d->d_name);
if (stat(filename, &st) == -1)
continue;
while ((d = readdir(fdir)) != NULL) {
// Fixed in OPM:
// don't show current and parent dir entries twice
if (!(Q_stricmp(d->d_name, ".") && Q_stricmp(d->d_name, "..")) && Q_stricmp(d->d_name, "cvs")) {
continue;
}
if (st.st_mode & S_IFDIR) {
if (Q_stricmp(d->d_name, ".") && Q_stricmp(d->d_name, "..")) {
if (strlen(subdirs)) {
Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s/%s", subdirs, d->d_name);
}
else {
Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s", d->d_name);
}
Sys_ListFilteredFiles( basedir, newsubdirs, filter, list, numfiles );
}
}
if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
break;
}
Com_sprintf( filename, sizeof(filename), "%s/%s", subdirs, d->d_name );
if (!Com_FilterPath( filter, filename, qfalse ))
continue;
list[ *numfiles ] = CopyString( filename );
(*numfiles)++;
}
Com_sprintf(filename, sizeof(filename), "%s/%s", search, d->d_name);
if (stat(filename, &st) == -1) {
continue;
}
closedir(fdir);
if ((st.st_mode & S_IFDIR) != 0 && wantsubs) {
if (strlen(subdirs)) {
Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s/%s", subdirs, d->d_name);
} else {
Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", d->d_name);
}
// recursively iterate into subdirectory
Sys_ListFilteredFiles(basedir, newsubdirs, filter, wantsubs, list, numfiles);
}
if (*numfiles >= MAX_FOUND_FILES - 1) {
break;
}
if (strlen(subdirs)) {
Com_sprintf(filename, sizeof(filename), "%s/%s", subdirs, d->d_name);
} else {
Q_strncpyz(filename, d->d_name, sizeof(filename));
}
if (!Com_FilterPath(filter, filename, qfalse)) {
continue;
}
list[*numfiles] = CopyString(filename);
(*numfiles)++;
}
closedir(fdir);
}
/*
@ -430,104 +446,105 @@ void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, ch
Sys_ListFiles
==================
*/
char **Sys_ListFiles( const char *directory, const char *extension, const char *filter, int *numfiles, qboolean wantsubs )
char **Sys_ListFiles(const char *directory, const char *extension, const char *filter, int *numfiles, qboolean wantsubs)
{
struct dirent *d;
DIR *fdir;
qboolean dironly = wantsubs;
char search[MAX_OSPATH];
int nfiles;
char **listCopy;
char *list[MAX_FOUND_FILES];
int i;
struct stat st;
struct dirent *d;
DIR *fdir;
char search[MAX_OSPATH];
int nfiles;
char **listCopy;
char *list[MAX_FOUND_FILES];
int i;
struct stat st;
char buffer[64];
int extLen;
if (directory[0] == '\0') {
*numfiles = 0;
return NULL;
}
if (filter) {
if (!extension) {
extension = "";
}
nfiles = 0;
Sys_ListFilteredFiles( directory, "", filter, list, &nfiles );
// passing a slash as extension will find directories,
// anything else looks only for files with that extension
if (!filter && (extension[0] != '/' || extension[1])) {
Q_snprintf(buffer, sizeof(buffer), "*%s", extension);
filter = buffer;
}
list[ nfiles ] = NULL;
*numfiles = nfiles;
if (filter) {
nfiles = 0;
Sys_ListFilteredFiles(directory, "", filter, wantsubs, list, &nfiles);
if (!nfiles)
return NULL;
list[nfiles] = NULL;
*numfiles = nfiles;
if (!nfiles) {
return NULL;
}
listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) );
for ( i = 0 ; i < nfiles ; i++ ) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
listCopy = Z_Malloc((nfiles + 1) * sizeof(*listCopy));
for (i = 0; i < nfiles; i++) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
return listCopy;
}
return listCopy;
}
if ( directory[0] == '\0' ) {
*numfiles = 0;
return NULL;
}
// only enumerate directories from this point onward
if ( !extension)
extension = "";
// search
nfiles = 0;
if ( extension[0] == '/' && extension[1] == 0 ) {
extension = "";
dironly = qtrue;
}
if ((fdir = opendir(directory)) == NULL) {
*numfiles = 0;
return NULL;
}
extLen = strlen( extension );
while ((d = readdir(fdir)) != NULL) {
Com_sprintf(search, sizeof(search), "%s/%s", directory, d->d_name);
if (stat(search, &st) == -1) {
continue;
}
// search
nfiles = 0;
// Fixed in OPM:
// don't show current and parent dir entries twice
if (!(Q_stricmp(d->d_name, ".") && Q_stricmp(d->d_name, "..") && Q_stricmp(d->d_name, "cvs"))) {
continue;
}
if ((fdir = opendir(directory)) == NULL) {
*numfiles = 0;
return NULL;
}
if ((st.st_mode & S_IFDIR) == 0) {
continue;
}
while ((d = readdir(fdir)) != NULL) {
Com_sprintf(search, sizeof(search), "%s/%s", directory, d->d_name);
if (stat(search, &st) == -1)
continue;
if ((dironly && !(st.st_mode & S_IFDIR)) ||
(!dironly && (st.st_mode & S_IFDIR)))
continue;
if (nfiles == MAX_FOUND_FILES - 1) {
break;
}
if (*extension) {
if ( strlen( d->d_name ) < extLen ||
Q_stricmp(
d->d_name + strlen( d->d_name ) - extLen,
extension ) ) {
continue; // didn't match
}
}
list[nfiles] = CopyString(d->d_name);
nfiles++;
}
if ( nfiles == MAX_FOUND_FILES - 1 )
break;
list[ nfiles ] = CopyString( d->d_name );
nfiles++;
}
list[nfiles] = NULL;
list[ nfiles ] = NULL;
closedir(fdir);
closedir(fdir);
// return a copy of the list
*numfiles = nfiles;
// return a copy of the list
*numfiles = nfiles;
if (!nfiles) {
return NULL;
}
if ( !nfiles ) {
return NULL;
}
listCopy = Z_Malloc((nfiles + 1) * sizeof(*listCopy));
for (i = 0; i < nfiles; i++) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) );
for ( i = 0 ; i < nfiles ; i++ ) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
return listCopy;
return listCopy;
}
/*

View file

@ -477,56 +477,78 @@ DIRECTORY SCANNING
Sys_ListFilteredFiles
==============
*/
void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **list, int *numfiles )
void Sys_ListFilteredFiles(
const char *basedir, const char *subdirs, char *filter, qboolean wantsubs, char **list, int *numfiles
)
{
char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
char filename[MAX_OSPATH];
intptr_t findhandle;
struct _finddata_t findinfo;
char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
char filename[MAX_OSPATH];
intptr_t findhandle;
struct _finddata_t findinfo;
if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
return;
}
if (*numfiles >= MAX_FOUND_FILES - 1) {
return;
}
if ( basedir[0] == '\0' ) {
return;
}
if (basedir[0] == '\0') {
return;
}
if (strlen(subdirs)) {
Com_sprintf( search, sizeof(search), "%s\\%s\\*", basedir, subdirs );
}
else {
Com_sprintf( search, sizeof(search), "%s\\*", basedir );
}
if (strlen(subdirs)) {
Com_sprintf(search, sizeof(search), "%s\\%s\\*", basedir, subdirs);
} else {
Com_sprintf(search, sizeof(search), "%s\\*", basedir);
}
findhandle = _findfirst (search, &findinfo);
if (findhandle == -1) {
return;
}
findhandle = _findfirst(search, &findinfo);
if (findhandle == -1) {
return;
}
do {
if (findinfo.attrib & _A_SUBDIR) {
if (Q_stricmp(findinfo.name, ".") && Q_stricmp(findinfo.name, "..")) {
if (strlen(subdirs)) {
Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s\\%s", subdirs, findinfo.name);
}
else {
Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s", findinfo.name);
}
Sys_ListFilteredFiles( basedir, newsubdirs, filter, list, numfiles );
}
}
if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
break;
}
Com_sprintf( filename, sizeof(filename), "%s\\%s", subdirs, findinfo.name );
if (!Com_FilterPath( filter, filename, qfalse ))
continue;
list[ *numfiles ] = CopyString( filename );
(*numfiles)++;
} while ( _findnext (findhandle, &findinfo) != -1 );
do {
// Fixed in OPM:
// don't show current and parent dir entries twice
if (!(Q_stricmp(findinfo.name, ".") && Q_stricmp(findinfo.name, "..") && Q_stricmp(findinfo.name, "cvs"))) {
continue;
}
_findclose (findhandle);
if ((findinfo.attrib & _A_SUBDIR) != 0 && wantsubs) {
if (strlen(subdirs)) {
Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s\\%s\\*", subdirs, findinfo.name);
} else {
Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", findinfo.name);
}
// recursively iterate into subdirectory
Sys_ListFilteredFiles(basedir, newsubdirs, filter, wantsubs, list, numfiles);
}
if (*numfiles >= MAX_FOUND_FILES - 1) {
break;
}
if (strlen(subdirs)) {
Com_sprintf(filename, sizeof(filename), "%s\\%s", subdirs, findinfo.name);
} else {
Q_strncpyz(filename, findinfo.name, sizeof(filename));
}
if (!Com_FilterPath(filter, filename, qfalse)) {
continue;
}
list[*numfiles] = CopyString(filename);
// replace backslashes with forward slashes, if any
// FS_ReplaceSeparators would be nice but it does the opposite
for (char *c = strchr(list[*numfiles], '\\'); c; c = strchr(list[*numfiles], '\\')) {
*c = '/';
}
(*numfiles)++;
} while (_findnext(findhandle, &findinfo) != -1);
_findclose(findhandle);
}
/*
@ -536,24 +558,24 @@ strgtr
*/
static qboolean strgtr(const char *s0, const char *s1)
{
int l0, l1, i;
int l0, l1, i;
l0 = strlen(s0);
l1 = strlen(s1);
l0 = strlen(s0);
l1 = strlen(s1);
if (l1<l0) {
l0 = l1;
}
if (l1 < l0) {
l0 = l1;
}
for(i=0;i<l0;i++) {
if (s1[i] > s0[i]) {
return qtrue;
}
if (s1[i] < s0[i]) {
return qfalse;
}
}
return qfalse;
for (i = 0; i < l0; i++) {
if (s1[i] > s0[i]) {
return qtrue;
}
if (s1[i] < s0[i]) {
return qfalse;
}
}
return qfalse;
}
/*
@ -561,116 +583,121 @@ static qboolean strgtr(const char *s0, const char *s1)
Sys_ListFiles
==============
*/
char **Sys_ListFiles( const char *directory, const char *extension, const char *filter, int *numfiles, qboolean wantsubs )
char **Sys_ListFiles(const char *directory, const char *extension, const char *filter, int *numfiles, qboolean wantsubs)
{
char search[MAX_OSPATH];
int nfiles;
char **listCopy;
char *list[MAX_FOUND_FILES];
struct _finddata_t findinfo;
intptr_t findhandle;
int flag;
int i;
int extLen;
char search[MAX_OSPATH];
int nfiles;
char **listCopy;
char *list[MAX_FOUND_FILES] = {NULL};
struct _finddata_t findinfo;
intptr_t findhandle;
qboolean swapped;
int i;
char buffer[64];
if (filter) {
if (directory[0] == NULL) {
*numfiles = 0;
return NULL;
}
nfiles = 0;
Sys_ListFilteredFiles( directory, "", filter, list, &nfiles );
if (!extension) {
extension = "";
}
list[ nfiles ] = 0;
*numfiles = nfiles;
// passing a slash as extension will find directories,
// anything else looks only for files with that extension
if (!filter && (extension[0] != '/' || extension[1])) {
Q_snprintf(buffer, sizeof(buffer), "*%s", extension);
filter = buffer;
}
if (!nfiles)
return NULL;
if (filter) {
nfiles = 0;
Sys_ListFilteredFiles(directory, "", filter, wantsubs, list, &nfiles);
listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) );
for ( i = 0 ; i < nfiles ; i++ ) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
list[nfiles] = NULL;
*numfiles = nfiles;
if (!nfiles) {
return NULL;
}
return listCopy;
}
listCopy = Z_Malloc((nfiles + 1) * sizeof(*listCopy));
for (i = 0; i < nfiles; i++) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
if ( directory[0] == '\0' ) {
*numfiles = 0;
return NULL;
}
return listCopy;
}
if ( !extension) {
extension = "";
}
// only enumerate directories from this point onward
Com_sprintf(search, 256, "%s\\*", directory);
// passing a slash as extension will find directories
if ( extension[0] == '/' && extension[1] == 0 ) {
extension = "";
flag = 0;
} else {
flag = _A_SUBDIR;
}
// search
nfiles = 0;
findhandle = _findfirst(search, &findinfo);
if (findhandle == -1) {
*numfiles = 0;
return NULL;
}
extLen = strlen( extension );
do {
// Fixed in OPM:
// don't show current and parent dir entries twice
if (!(Q_stricmp(findinfo.name, ".") && Q_stricmp(findinfo.name, "..") && Q_stricmp(findinfo.name, "cvs"))) {
continue;
}
Com_sprintf( search, sizeof(search), "%s\\*%s", directory, extension );
if ((findinfo.attrib & _A_SUBDIR) == 0) {
continue;
}
// search
nfiles = 0;
if (nfiles >= MAX_FOUND_FILES - 1) {
break;
}
findhandle = _findfirst (search, &findinfo);
if (findhandle == -1) {
*numfiles = 0;
return NULL;
}
list[nfiles] = CopyString(findinfo.name);
do {
if ( (!wantsubs && flag ^ ( findinfo.attrib & _A_SUBDIR )) || (wantsubs && findinfo.attrib & _A_SUBDIR) ) {
if (*extension) {
if ( strlen( findinfo.name ) < extLen ||
Q_stricmp(
findinfo.name + strlen( findinfo.name ) - extLen,
extension ) ) {
continue; // didn't match
}
}
if ( nfiles == MAX_FOUND_FILES - 1 ) {
break;
}
list[ nfiles ] = CopyString( findinfo.name );
nfiles++;
}
} while ( _findnext (findhandle, &findinfo) != -1 );
// replace backslashes with forward slashes
// FS_ReplaceSeparators would be nice but it does the opposite
for (char *c = strchr(list[nfiles], '\\'); c; c = strchr(list[nfiles], '\\')) {
*c = '/';
}
list[ nfiles ] = 0;
++nfiles;
} while (_findnext(findhandle, &findinfo) != -1);
_findclose (findhandle);
list[nfiles] = NULL;
// return a copy of the list
*numfiles = nfiles;
_findclose(findhandle);
if ( !nfiles ) {
return NULL;
}
// return a copy of the list
*numfiles = nfiles;
listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) );
for ( i = 0 ; i < nfiles ; i++ ) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
if (!nfiles) {
return NULL;
}
do {
flag = 0;
for(i=1; i<nfiles; i++) {
if (strgtr(listCopy[i-1], listCopy[i])) {
char *temp = listCopy[i];
listCopy[i] = listCopy[i-1];
listCopy[i-1] = temp;
flag = 1;
}
}
} while(flag);
listCopy = Z_Malloc((nfiles + 1) * sizeof(*listCopy));
for (i = 0; i < nfiles; i++) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
return listCopy;
// bubble-sort name entries alphabetically, in ascending order
do {
swapped = qfalse;
for (i = 1; i < nfiles; i++) {
if (strgtr(listCopy[i - 1], listCopy[i])) {
char *temp = listCopy[i];
listCopy[i] = listCopy[i - 1];
listCopy[i - 1] = temp;
swapped = qtrue;
}
}
} while (swapped);
return listCopy;
}
/*