Merge branch 'master' of https://bitbucket.org/4coder/4coder
This commit is contained in:
commit
248125dbaa
|
@ -40,6 +40,8 @@ keycode_init(Display* dpy, Key_Codes *codes){
|
||||||
// rebound to esc, so there are two KeyCodes for the XK_Escape KeyCode but XKeysymToKeycode only
|
// rebound to esc, so there are two KeyCodes for the XK_Escape KeyCode but XKeysymToKeycode only
|
||||||
// gets one of them, hence the need for this crazy lookup which works correctly with rebound keys.
|
// gets one of them, hence the need for this crazy lookup which works correctly with rebound keys.
|
||||||
|
|
||||||
|
memset(keycode_lookup_table, 0, sizeof(keycode_lookup_table));
|
||||||
|
|
||||||
struct SymMapping {
|
struct SymMapping {
|
||||||
KeySym sym;
|
KeySym sym;
|
||||||
Code code;
|
Code code;
|
||||||
|
|
|
@ -31,6 +31,9 @@ typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp);
|
||||||
#define Sys_Set_File_List_Sig(name) void name(File_List *file_list, String directory)
|
#define Sys_Set_File_List_Sig(name) void name(File_List *file_list, String directory)
|
||||||
typedef Sys_Set_File_List_Sig(System_Set_File_List);
|
typedef Sys_Set_File_List_Sig(System_Set_File_List);
|
||||||
|
|
||||||
|
#define Sys_File_Paths_Equal_Sig(name) b32 name(char *path_a, char *path_b)
|
||||||
|
typedef Sys_File_Paths_Equal_Sig(System_File_Paths_Equal);
|
||||||
|
|
||||||
#define Sys_Post_Clipboard_Sig(name) void name(String str)
|
#define Sys_Post_Clipboard_Sig(name) void name(String str)
|
||||||
typedef Sys_Post_Clipboard_Sig(System_Post_Clipboard);
|
typedef Sys_Post_Clipboard_Sig(System_Post_Clipboard);
|
||||||
|
|
||||||
|
|
234
linux_4ed.cpp
234
linux_4ed.cpp
|
@ -60,6 +60,8 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
//#define FRED_USE_FONTCONFIG 1
|
//#define FRED_USE_FONTCONFIG 1
|
||||||
|
|
||||||
|
@ -367,38 +369,123 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sys_File_Paths_Equal_Sig(system_file_paths_equal){
|
||||||
|
b32 result = 0;
|
||||||
|
|
||||||
|
char* real_a = realpath(path_a, NULL);
|
||||||
|
if(real_a){
|
||||||
|
char* real_b = realpath(path_b, NULL);
|
||||||
|
if(real_b){
|
||||||
|
result = strcmp(real_a, real_b) == 0;
|
||||||
|
free(real_b);
|
||||||
|
}
|
||||||
|
free(real_a);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Sys_Post_Clipboard_Sig(system_post_clipboard){
|
Sys_Post_Clipboard_Sig(system_post_clipboard){
|
||||||
LinuxStringDup(&linuxvars.clipboard_outgoing, str.str, str.size);
|
LinuxStringDup(&linuxvars.clipboard_outgoing, str.str, str.size);
|
||||||
XSetSelectionOwner(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime);
|
XSetSelectionOwner(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Sys_CLI_Call_Sig(system_cli_call){
|
Sys_CLI_Call_Sig(system_cli_call){
|
||||||
// TODO(allen): Implement
|
// TODO(allen): Implement
|
||||||
DBG_FN;
|
|
||||||
AllowLocal(path);
|
// fprintf(stderr, "cli call: %s, %s\n", path, script_name);
|
||||||
AllowLocal(script_name);
|
|
||||||
AllowLocal(cli_out);
|
int pipe_fds[2];
|
||||||
|
if(pipe(pipe_fds) == -1){
|
||||||
|
perror("system_cli_call: pipe");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t child_pid = fork();
|
||||||
|
if(child_pid == -1){
|
||||||
|
perror("system_cli_call: fork");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum { PIPE_FD_READ, PIPE_FD_WRITE };
|
||||||
|
|
||||||
|
// child
|
||||||
|
if(child_pid == 0){
|
||||||
|
close(pipe_fds[PIPE_FD_READ]);
|
||||||
|
dup2(pipe_fds[PIPE_FD_WRITE], STDOUT_FILENO);
|
||||||
|
dup2(pipe_fds[PIPE_FD_WRITE], STDERR_FILENO);
|
||||||
|
|
||||||
|
if(chdir(path) == -1){
|
||||||
|
perror("system_cli_call: chdir");
|
||||||
|
exit(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
//TODO(inso): do spaces in script_name signify multiple args?
|
||||||
|
char* argv[] = { "sh", script_name, NULL };
|
||||||
|
|
||||||
|
if(execv("/bin/sh", argv) == -1){
|
||||||
|
perror("system_cli_call: execv");
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
close(pipe_fds[PIPE_FD_WRITE]);
|
||||||
|
|
||||||
|
*(pid_t*)&cli_out->proc = child_pid;
|
||||||
|
*(int*)&cli_out->out_read = pipe_fds[PIPE_FD_READ];
|
||||||
|
*(int*)&cli_out->out_write = pipe_fds[PIPE_FD_WRITE];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys_CLI_Begin_Update_Sig(system_cli_begin_update){
|
Sys_CLI_Begin_Update_Sig(system_cli_begin_update){
|
||||||
// TODO(allen): Implement
|
|
||||||
DBG_FN;
|
|
||||||
AllowLocal(cli);
|
AllowLocal(cli);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys_CLI_Update_Step_Sig(system_cli_update_step){
|
Sys_CLI_Update_Step_Sig(system_cli_update_step){
|
||||||
// TODO(allen): Implement
|
|
||||||
DBG_FN;
|
int pipe_read_fd = *(int*)&cli->out_read;
|
||||||
AllowLocal(cli);
|
|
||||||
AllowLocal(dest);
|
fd_set fds;
|
||||||
AllowLocal(max);
|
FD_ZERO(&fds);
|
||||||
AllowLocal(amount);
|
FD_SET(pipe_read_fd, &fds);
|
||||||
|
|
||||||
|
struct timeval tv = {};
|
||||||
|
|
||||||
|
size_t space_left = max;
|
||||||
|
char* ptr = dest;
|
||||||
|
|
||||||
|
while(space_left > 0 && select(pipe_read_fd + 1, &fds, NULL, NULL, &tv) == 1){
|
||||||
|
ssize_t num = read(pipe_read_fd, ptr, space_left);
|
||||||
|
if(num == -1){
|
||||||
|
perror("system_cli_update_step: read");
|
||||||
|
} else if(num == 0){
|
||||||
|
// NOTE(inso): EOF
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
ptr += num;
|
||||||
|
space_left -= num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*amount = (ptr - dest);
|
||||||
|
return (ptr - dest) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys_CLI_End_Update_Sig(system_cli_end_update){
|
Sys_CLI_End_Update_Sig(system_cli_end_update){
|
||||||
// TODO(allen): Implement
|
pid_t pid = *(pid_t*)&cli->proc;
|
||||||
DBG_FN;
|
b32 close_me = 0;
|
||||||
AllowLocal(cli);
|
|
||||||
|
int status;
|
||||||
|
if(waitpid(pid, &status, WNOHANG) > 0){
|
||||||
|
close_me = 1;
|
||||||
|
cli->exit = WEXITSTATUS(status);
|
||||||
|
close(*(int*)&cli->out_read);
|
||||||
|
close(*(int*)&cli->out_write);
|
||||||
|
}
|
||||||
|
|
||||||
|
return close_me;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(sizeof(Plat_Handle) >= sizeof(Linux_Semaphore_Handle), "Plat_Handle not big enough");
|
static_assert(sizeof(Plat_Handle) >= sizeof(Linux_Semaphore_Handle), "Plat_Handle not big enough");
|
||||||
|
@ -470,7 +557,6 @@ ThreadProc(void* arg){
|
||||||
|
|
||||||
Sys_Post_Job_Sig(system_post_job){
|
Sys_Post_Job_Sig(system_post_job){
|
||||||
// TODO(allen): Implement
|
// TODO(allen): Implement
|
||||||
DBG_FN;
|
|
||||||
AllowLocal(group_id);
|
AllowLocal(group_id);
|
||||||
AllowLocal(job);
|
AllowLocal(job);
|
||||||
|
|
||||||
|
@ -513,7 +599,6 @@ Sys_Release_Lock_Sig(system_release_lock){
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys_Cancel_Job_Sig(system_cancel_job){
|
Sys_Cancel_Job_Sig(system_cancel_job){
|
||||||
DBG_FN;
|
|
||||||
AllowLocal(group_id);
|
AllowLocal(group_id);
|
||||||
AllowLocal(job_id);
|
AllowLocal(job_id);
|
||||||
|
|
||||||
|
@ -573,11 +658,16 @@ INTERNAL_Sys_Sentinel_Sig(internal_sentinel){
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL_Sys_Get_Thread_States_Sig(internal_get_thread_states){
|
INTERNAL_Sys_Get_Thread_States_Sig(internal_get_thread_states){
|
||||||
// TODO(allen): Implement
|
Work_Queue *queue = exchange_vars.thread.queues + id;
|
||||||
DBG_FN;
|
u32 write = queue->write_position;
|
||||||
AllowLocal(id);
|
u32 read = queue->read_position;
|
||||||
AllowLocal(running);
|
if (write < read) write += JOB_ID_WRAP;
|
||||||
AllowLocal(pending);
|
*pending = (i32)(write - read);
|
||||||
|
|
||||||
|
Thread_Group *group = linuxvars.groups + id;
|
||||||
|
for (i32 i = 0; i < group->count; ++i){
|
||||||
|
running[i] = (group->threads[i].running != 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL_Sys_Debug_Message_Sig(internal_debug_message){
|
INTERNAL_Sys_Debug_Message_Sig(internal_debug_message){
|
||||||
|
@ -585,34 +675,70 @@ INTERNAL_Sys_Debug_Message_Sig(internal_debug_message){
|
||||||
}
|
}
|
||||||
|
|
||||||
DIRECTORY_HAS_FILE_SIG(system_directory_has_file){
|
DIRECTORY_HAS_FILE_SIG(system_directory_has_file){
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
//TODO(inso): implement
|
fprintf(stderr, "system_directory_has_file: %.*s %s\n", dir.size, dir.str, filename);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
char buff[PATH_MAX] = {};
|
char buff[PATH_MAX] = {};
|
||||||
|
size_t fnamesize = strlen(filename);
|
||||||
|
|
||||||
|
if(fnamesize + dir.size + 1 > PATH_MAX){
|
||||||
|
fprintf(stderr, "system_directory_has_file: path too long");
|
||||||
|
} else {
|
||||||
memcpy(buff, dir.str, dir.size);
|
memcpy(buff, dir.str, dir.size);
|
||||||
printf("Has file %s\n", buff);
|
memcpy(buff + dir.size, filename, fnamesize + 1);
|
||||||
|
struct stat st;
|
||||||
|
result = stat(buff, &st) == 0 && S_ISREG(st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
DIRECTORY_CD_SIG(system_directory_cd){
|
DIRECTORY_CD_SIG(system_directory_cd){
|
||||||
int result = 0;
|
|
||||||
// TODO(allen): Implement
|
|
||||||
|
|
||||||
printf("Dir CD: %.*s\n", dir->size, dir->str);
|
fprintf(stderr, "system_directory_cd: %.*s %s\n", dir->size, dir->str, rel_path);
|
||||||
|
|
||||||
|
b32 result = 0;
|
||||||
|
i32 old_size;
|
||||||
|
i32 len;
|
||||||
|
|
||||||
|
if (rel_path[0] != 0){
|
||||||
|
if (rel_path[0] == '.' && rel_path[1] == 0){
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
else if (rel_path[0] == '.' && rel_path[1] == '.' && rel_path[2] == 0){
|
||||||
|
result = remove_last_folder(dir);
|
||||||
|
terminate_with_null(dir);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
len = str_size(rel_path);
|
||||||
|
if (dir->size + len + 1 > dir->memory_size){
|
||||||
|
old_size = dir->size;
|
||||||
|
append_partial(dir, rel_path);
|
||||||
|
append_partial(dir, "/");
|
||||||
|
terminate_with_null(dir);
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if(stat(dir->str, &st) == -1){
|
||||||
|
perror("system_directory_cd: stat");
|
||||||
|
result = 0;
|
||||||
|
} else {
|
||||||
|
result = S_ISDIR(st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!result){
|
||||||
|
dir->size = old_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AllowLocal(dir);
|
|
||||||
AllowLocal(rel_path);
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
Sys_File_Can_Be_Made(system_file_can_be_made){
|
Sys_File_Can_Be_Made(system_file_can_be_made){
|
||||||
// TODO(allen): Implement
|
return access(filename, W_OK) == 0;
|
||||||
|
|
||||||
printf("File can be made: %s\n", filename);
|
|
||||||
AllowLocal(filename);
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
|
@ -1064,19 +1190,49 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
|
||||||
printf("GL_VERSION: %s\n", Version);
|
printf("GL_VERSION: %s\n", Version);
|
||||||
printf("GL_EXTENSIONS: %s\n", Extensions);
|
printf("GL_EXTENSIONS: %s\n", Extensions);
|
||||||
|
|
||||||
//TODO(inso): this should be optional
|
//TODO(inso): enable vsync if available. this should probably be optional
|
||||||
if(strstr(glxExts, "GLX_EXT_swap_control ")){
|
if(strstr(glxExts, "GLX_EXT_swap_control ")){
|
||||||
PFNGLXSWAPINTERVALEXTPROC glx_swap_interval =
|
PFNGLXSWAPINTERVALEXTPROC glx_swap_interval_ext =
|
||||||
(PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT");
|
(PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT");
|
||||||
|
|
||||||
if(glx_swap_interval){
|
if(glx_swap_interval_ext){
|
||||||
glx_swap_interval(XDisplay, XWindow, 1);
|
glx_swap_interval_ext(XDisplay, XWindow, 1);
|
||||||
|
|
||||||
unsigned int swap_val = 0;
|
unsigned int swap_val = 0;
|
||||||
glXQueryDrawable(XDisplay, XWindow, GLX_SWAP_INTERVAL_EXT, &swap_val);
|
glXQueryDrawable(XDisplay, XWindow, GLX_SWAP_INTERVAL_EXT, &swap_val);
|
||||||
linuxvars.vsync = swap_val == 1;
|
linuxvars.vsync = swap_val == 1;
|
||||||
printf("VSync enabled? %d\n", linuxvars.vsync);
|
printf("VSync enabled? %d\n", linuxvars.vsync);
|
||||||
}
|
}
|
||||||
|
} else if(strstr(glxExts, "GLX_MESA_swap_control ")){
|
||||||
|
PFNGLXSWAPINTERVALMESAPROC glx_swap_interval_mesa =
|
||||||
|
(PFNGLXSWAPINTERVALMESAPROC) glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalMESA");
|
||||||
|
|
||||||
|
PFNGLXGETSWAPINTERVALMESAPROC glx_get_swap_interval_mesa =
|
||||||
|
(PFNGLXGETSWAPINTERVALMESAPROC) glXGetProcAddressARB((const GLubyte*)"glXGetSwapIntervalMESA");
|
||||||
|
|
||||||
|
if(glx_swap_interval_mesa){
|
||||||
|
glx_swap_interval_mesa(1);
|
||||||
|
if(glx_get_swap_interval_mesa){
|
||||||
|
linuxvars.vsync = glx_get_swap_interval_mesa();
|
||||||
|
printf("VSync enabled? %d (MESA)\n", linuxvars.vsync);
|
||||||
|
} else {
|
||||||
|
// NOTE(inso): assume it worked?
|
||||||
|
linuxvars.vsync = 1;
|
||||||
|
puts("VSync enabled? possibly (MESA)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(strstr(glxExts, "GLX_SGI_swap_control ")){
|
||||||
|
PFNGLXSWAPINTERVALSGIPROC glx_swap_interval_sgi =
|
||||||
|
(PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalSGI");
|
||||||
|
|
||||||
|
if(glx_swap_interval_sgi){
|
||||||
|
glx_swap_interval_sgi(1);
|
||||||
|
//NOTE(inso): The SGI one doesn't seem to have a way to confirm we got it...
|
||||||
|
linuxvars.vsync = 1;
|
||||||
|
puts("VSync enabled? hopefully (SGI)");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puts("VSync enabled? nope, no suitable extension");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FRED_INTERNAL
|
#if FRED_INTERNAL
|
||||||
|
|
|
@ -495,6 +495,17 @@ DIRECTORY_CD_SIG(system_directory_cd){
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sys_File_Paths_Equal_Sig(system_file_paths_equal){
|
||||||
|
b32 result = 0;
|
||||||
|
|
||||||
|
// TODO(someone who knows windows): implement me
|
||||||
|
|
||||||
|
AllowLocal(path_a);
|
||||||
|
AllowLocal(path_b);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
Sys_Post_Clipboard_Sig(system_post_clipboard){
|
Sys_Post_Clipboard_Sig(system_post_clipboard){
|
||||||
if (OpenClipboard(win32vars.window_handle)){
|
if (OpenClipboard(win32vars.window_handle)){
|
||||||
|
|
Loading…
Reference in New Issue