fix set_file_list a bit + add clipboard paste
parent
2f1486c9dd
commit
edd6ead966
457
linux_4ed.cpp
457
linux_4ed.cpp
|
@ -72,7 +72,11 @@ struct Linux_Vars{
|
||||||
Mouse_State mouse_data;
|
Mouse_State mouse_data;
|
||||||
|
|
||||||
String clipboard_contents;
|
String clipboard_contents;
|
||||||
|
String clipboard_outgoing;
|
||||||
|
|
||||||
|
Atom atom_CLIPBOARD;
|
||||||
|
Atom atom_UTF8_STRING;
|
||||||
|
|
||||||
void *app_code;
|
void *app_code;
|
||||||
void *custom;
|
void *custom;
|
||||||
|
|
||||||
|
@ -89,6 +93,8 @@ struct Linux_Vars{
|
||||||
Font_Load_System fnt;
|
Font_Load_System fnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LINUX_MAX_PASTE_CHARS 0x10000L
|
||||||
|
|
||||||
globalvar Linux_Vars linuxvars;
|
globalvar Linux_Vars linuxvars;
|
||||||
globalvar Application_Memory memory_vars;
|
globalvar Application_Memory memory_vars;
|
||||||
globalvar Exchange exchange_vars;
|
globalvar Exchange exchange_vars;
|
||||||
|
@ -180,6 +186,21 @@ Sys_Free_Memory_Sig(system_free_memory){
|
||||||
LinuxFreeMemory(block);
|
LinuxFreeMemory(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
LinuxStringDup(String* str, void* data, size_t size){
|
||||||
|
if(str->memory_size < size){
|
||||||
|
if(str->str){
|
||||||
|
LinuxFreeMemory(str->str);
|
||||||
|
}
|
||||||
|
str->memory_size = size;
|
||||||
|
str->str = (char*)LinuxGetMemory(size);
|
||||||
|
//TODO(inso): handle alloc failure case
|
||||||
|
}
|
||||||
|
|
||||||
|
str->size = size;
|
||||||
|
memcpy(str->str, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
#if (defined(_BSD_SOURCE) || defined(_SVID_SOURCE))
|
#if (defined(_BSD_SOURCE) || defined(_SVID_SOURCE))
|
||||||
#define TimeBySt
|
#define TimeBySt
|
||||||
#endif
|
#endif
|
||||||
|
@ -231,9 +252,11 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
||||||
i32 count, file_count, size, required_size;
|
i32 count, file_count, size, required_size;
|
||||||
|
|
||||||
terminate_with_null(&directory);
|
terminate_with_null(&directory);
|
||||||
|
|
||||||
d = opendir(directory.str);
|
d = opendir(directory.str);
|
||||||
if (d){
|
if (d){
|
||||||
count = 0;
|
count = 0;
|
||||||
|
file_count = 0;
|
||||||
for (entry = readdir(d);
|
for (entry = readdir(d);
|
||||||
entry != 0;
|
entry != 0;
|
||||||
entry = readdir(d)){
|
entry = readdir(d)){
|
||||||
|
@ -242,7 +265,6 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
||||||
for (size = 0; fname[size]; ++size);
|
for (size = 0; fname[size]; ++size);
|
||||||
count += size + 1;
|
count += size + 1;
|
||||||
}
|
}
|
||||||
closedir(d);
|
|
||||||
|
|
||||||
required_size = count + file_count * sizeof(File_Info);
|
required_size = count + file_count * sizeof(File_Info);
|
||||||
if (file_list->block_size < required_size){
|
if (file_list->block_size < required_size){
|
||||||
|
@ -253,33 +275,41 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
||||||
file_list->infos = (File_Info*)file_list->block;
|
file_list->infos = (File_Info*)file_list->block;
|
||||||
cursor = (char*)(file_list->infos + file_count);
|
cursor = (char*)(file_list->infos + file_count);
|
||||||
|
|
||||||
d = opendir(directory.str);
|
rewinddir(d);
|
||||||
if (d){
|
info_ptr = file_list->infos;
|
||||||
info_ptr = file_list->infos;
|
for (entry = readdir(d);
|
||||||
for (entry = readdir(d);
|
entry != 0;
|
||||||
entry != 0;
|
entry = readdir(d), ++info_ptr){
|
||||||
entry = readdir(d), ++info_ptr){
|
fname = entry->d_name;
|
||||||
fname = entry->d_name;
|
cursor_start = cursor;
|
||||||
cursor_start = cursor;
|
for (; *fname; ) *cursor++ = *fname++;
|
||||||
for (; *fname; ) *cursor++ = *fname++;
|
|
||||||
|
|
||||||
// TODO(allen): detect file/folder status
|
#ifdef _DIRENT_HAVE_D_TYPE
|
||||||
// (also make sure this even GETS folders!!!)
|
if(entry->d_type != DT_UNKNOWN){
|
||||||
info_ptr->folder = 0;
|
info_ptr->folder = entry->d_type == DT_DIR;
|
||||||
info_ptr->filename.str = cursor_start;
|
} else
|
||||||
info_ptr->filename.size = (i32)(cursor - cursor_start);
|
#endif
|
||||||
*cursor++ = 0;
|
{
|
||||||
info_ptr->filename.memory_size = info_ptr->filename.size + 1;
|
struct stat st;
|
||||||
|
if(lstat(entry->d_name, &st) != -1){
|
||||||
|
info_ptr->folder = S_ISDIR(st.st_mode);
|
||||||
|
} else {
|
||||||
|
info_ptr->folder = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info_ptr->filename.str = cursor_start;
|
||||||
|
info_ptr->filename.size = (i32)(cursor - cursor_start);
|
||||||
|
*cursor++ = 0;
|
||||||
|
info_ptr->filename.memory_size = info_ptr->filename.size + 1;
|
||||||
}
|
}
|
||||||
closedir(d);
|
closedir(d);
|
||||||
}
|
}
|
||||||
closedir(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys_Post_Clipboard_Sig(system_post_clipboard){
|
Sys_Post_Clipboard_Sig(system_post_clipboard){
|
||||||
// TODO(allen): Implement
|
LinuxStringDup(&linuxvars.clipboard_outgoing, str.str, str.size);
|
||||||
AllowLocal(str);
|
XSetSelectionOwner(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys_CLI_Call_Sig(system_cli_call){
|
Sys_CLI_Call_Sig(system_cli_call){
|
||||||
|
@ -573,6 +603,8 @@ LinuxLoadSystemCode(){
|
||||||
linuxvars.system->internal_sentinel = internal_sentinel;
|
linuxvars.system->internal_sentinel = internal_sentinel;
|
||||||
linuxvars.system->internal_get_thread_states = internal_get_thread_states;
|
linuxvars.system->internal_get_thread_states = internal_get_thread_states;
|
||||||
linuxvars.system->internal_debug_message = internal_debug_message;
|
linuxvars.system->internal_debug_message = internal_debug_message;
|
||||||
|
|
||||||
|
linuxvars.system->slash = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -591,7 +623,7 @@ LinuxRedrawTarget(){
|
||||||
system_acquire_lock(RENDER_LOCK);
|
system_acquire_lock(RENDER_LOCK);
|
||||||
launch_rendering(&linuxvars.target);
|
launch_rendering(&linuxvars.target);
|
||||||
system_release_lock(RENDER_LOCK);
|
system_release_lock(RENDER_LOCK);
|
||||||
glFlush();
|
// glFlush();
|
||||||
glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow);
|
glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,70 +1290,76 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!window_setup_success){
|
||||||
|
fprintf(stderr, "Error creating window.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
XSetICFocus(linuxvars.input_context);
|
XSetICFocus(linuxvars.input_context);
|
||||||
|
|
||||||
if (window_setup_success){
|
|
||||||
linuxvars.app.init(linuxvars.system, &linuxvars.target,
|
|
||||||
&memory_vars, &exchange_vars, &linuxvars.key_codes,
|
|
||||||
linuxvars.clipboard_contents, current_directory,
|
|
||||||
linuxvars.custom_api);
|
|
||||||
|
|
||||||
LinuxResizeTarget(WinWidth, WinHeight);
|
linuxvars.atom_CLIPBOARD = XInternAtom(linuxvars.XDisplay, "CLIPBOARD", False);
|
||||||
|
linuxvars.atom_UTF8_STRING = XInternAtom(linuxvars.XDisplay, "UTF8_STRING", False);
|
||||||
|
|
||||||
Atom WM_DELETE_WINDOW = XInternAtom(linuxvars.XDisplay, "WM_DELETE_WINDOW", False);
|
Atom WM_DELETE_WINDOW = XInternAtom(linuxvars.XDisplay, "WM_DELETE_WINDOW", False);
|
||||||
if(WM_DELETE_WINDOW != None){
|
if(WM_DELETE_WINDOW != None){
|
||||||
XSetWMProtocols(linuxvars.XDisplay, linuxvars.XWindow, &WM_DELETE_WINDOW, 1);
|
XSetWMProtocols(linuxvars.XDisplay, linuxvars.XWindow, &WM_DELETE_WINDOW, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 keep_running = 1;
|
linuxvars.app.init(linuxvars.system, &linuxvars.target,
|
||||||
|
&memory_vars, &exchange_vars, &linuxvars.key_codes,
|
||||||
|
linuxvars.clipboard_contents, current_directory,
|
||||||
|
linuxvars.custom_api);
|
||||||
|
|
||||||
while(keep_running)
|
LinuxResizeTarget(WinWidth, WinHeight);
|
||||||
|
b32 keep_running = 1;
|
||||||
|
|
||||||
|
while(keep_running)
|
||||||
|
{
|
||||||
|
XEvent PrevEvent = {};
|
||||||
|
|
||||||
|
while(XPending(linuxvars.XDisplay))
|
||||||
{
|
{
|
||||||
XEvent PrevEvent = {};
|
XEvent Event;
|
||||||
|
XNextEvent(linuxvars.XDisplay, &Event);
|
||||||
|
|
||||||
while(XPending(linuxvars.XDisplay))
|
if (XFilterEvent(&Event, None) == True){
|
||||||
{
|
continue;
|
||||||
XEvent Event;
|
}
|
||||||
XNextEvent(linuxvars.XDisplay, &Event);
|
|
||||||
|
|
||||||
if (XFilterEvent(&Event, None) == True){
|
switch (Event.type){
|
||||||
continue;
|
case KeyPress: {
|
||||||
}
|
b32 is_hold =
|
||||||
|
PrevEvent.type == KeyRelease &&
|
||||||
|
PrevEvent.xkey.time == Event.xkey.time &&
|
||||||
|
PrevEvent.xkey.keycode == Event.xkey.keycode;
|
||||||
|
|
||||||
switch (Event.type){
|
b8 mods[CONTROL_KEY_COUNT] = {};
|
||||||
case KeyPress: {
|
if(Event.xkey.state & ShiftMask) mods[CONTROL_KEY_SHIFT] = 1;
|
||||||
b32 is_hold =
|
if(Event.xkey.state & ControlMask) mods[CONTROL_KEY_CONTROL] = 1;
|
||||||
PrevEvent.type == KeyRelease &&
|
if(Event.xkey.state & LockMask) mods[CONTROL_KEY_CAPS] = 1;
|
||||||
PrevEvent.xkey.time == Event.xkey.time &&
|
if(Event.xkey.state & Mod1Mask) mods[CONTROL_KEY_ALT] = 1;
|
||||||
PrevEvent.xkey.keycode == Event.xkey.keycode;
|
// NOTE(inso): mod5 == AltGr
|
||||||
|
// if(Event.xkey.state & Mod5Mask) mods[CONTROL_KEY_ALT] = 1;
|
||||||
|
|
||||||
b8 mods[CONTROL_KEY_COUNT] = {};
|
KeySym keysym = NoSymbol;
|
||||||
if(Event.xkey.state & ShiftMask) mods[CONTROL_KEY_SHIFT] = 1;
|
char buff[32], no_caps_buff[32];
|
||||||
if(Event.xkey.state & ControlMask) mods[CONTROL_KEY_CONTROL] = 1;
|
|
||||||
if(Event.xkey.state & LockMask) mods[CONTROL_KEY_CAPS] = 1;
|
|
||||||
if(Event.xkey.state & Mod1Mask) mods[CONTROL_KEY_ALT] = 1;
|
|
||||||
// NOTE(inso): mod5 == AltGr
|
|
||||||
// if(Event.xkey.state & Mod5Mask) mods[CONTROL_KEY_ALT] = 1;
|
|
||||||
|
|
||||||
KeySym keysym = NoSymbol;
|
// NOTE(inso): Turn ControlMask off like the win32 code does.
|
||||||
char buff[32], no_caps_buff[32];
|
if(mods[CONTROL_KEY_CONTROL] && !mods[CONTROL_KEY_ALT]){
|
||||||
|
Event.xkey.state &= ~(ControlMask);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE(inso): Turn ControlMask off like the win32 code does.
|
// TODO(inso): Use one of the Xutf8LookupString funcs to allow for non-ascii chars
|
||||||
if(mods[CONTROL_KEY_CONTROL] && !mods[CONTROL_KEY_ALT]){
|
XLookupString(&Event.xkey, buff, sizeof(buff), &keysym, NULL);
|
||||||
Event.xkey.state &= ~(ControlMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(inso): Use one of the Xutf8LookupString funcs to allow for non-ascii chars
|
Event.xkey.state &= ~LockMask;
|
||||||
XLookupString(&Event.xkey, buff, sizeof(buff), &keysym, NULL);
|
XLookupString(&Event.xkey, no_caps_buff, sizeof(no_caps_buff), NULL, NULL);
|
||||||
|
|
||||||
Event.xkey.state &= ~LockMask;
|
u8 key = keycode_lookup(Event.xkey.keycode);
|
||||||
XLookupString(&Event.xkey, no_caps_buff, sizeof(no_caps_buff), NULL, NULL);
|
|
||||||
|
|
||||||
u8 key = keycode_lookup(Event.xkey.keycode);
|
if(key){
|
||||||
|
push_key(key, 0, 0, &mods, is_hold);
|
||||||
if(key){
|
} else {
|
||||||
push_key(key, 0, 0, &mods, is_hold);
|
|
||||||
} else {
|
|
||||||
key = buff[0] & 0xFF;
|
key = buff[0] & 0xFF;
|
||||||
if(key < 128){
|
if(key < 128){
|
||||||
u8 no_caps_key = no_caps_buff[0] & 0xFF;
|
u8 no_caps_key = no_caps_buff[0] & 0xFF;
|
||||||
|
@ -1331,113 +1369,202 @@ main(int argc, char **argv)
|
||||||
} else {
|
} else {
|
||||||
push_key(0, 0, 0, &mods, is_hold);
|
push_key(0, 0, 0, &mods, is_hold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case MotionNotify: {
|
case MotionNotify: {
|
||||||
linuxvars.mouse_data.x = Event.xmotion.x;
|
linuxvars.mouse_data.x = Event.xmotion.x;
|
||||||
linuxvars.mouse_data.y = Event.xmotion.y;
|
linuxvars.mouse_data.y = Event.xmotion.y;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case ButtonPress: {
|
case ButtonPress: {
|
||||||
switch(Event.xbutton.button){
|
switch(Event.xbutton.button){
|
||||||
case Button1: {
|
case Button1: {
|
||||||
linuxvars.mouse_data.left_button_pressed = 1;
|
linuxvars.mouse_data.left_button_pressed = 1;
|
||||||
linuxvars.mouse_data.left_button = 1;
|
linuxvars.mouse_data.left_button = 1;
|
||||||
} break;
|
} break;
|
||||||
case Button3: {
|
case Button3: {
|
||||||
linuxvars.mouse_data.right_button_pressed = 1;
|
linuxvars.mouse_data.right_button_pressed = 1;
|
||||||
linuxvars.mouse_data.right_button = 1;
|
linuxvars.mouse_data.right_button = 1;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case ButtonRelease: {
|
|
||||||
switch(Event.xbutton.button){
|
|
||||||
case Button1: {
|
|
||||||
linuxvars.mouse_data.left_button_released = 1;
|
|
||||||
linuxvars.mouse_data.left_button = 0;
|
|
||||||
} break;
|
|
||||||
case Button3: {
|
|
||||||
linuxvars.mouse_data.right_button_released = 1;
|
|
||||||
linuxvars.mouse_data.right_button = 0;
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case EnterNotify: {
|
case ButtonRelease: {
|
||||||
linuxvars.mouse_data.out_of_window = 0;
|
switch(Event.xbutton.button){
|
||||||
}break;
|
case Button1: {
|
||||||
|
linuxvars.mouse_data.left_button_released = 1;
|
||||||
|
linuxvars.mouse_data.left_button = 0;
|
||||||
|
} break;
|
||||||
|
case Button3: {
|
||||||
|
linuxvars.mouse_data.right_button_released = 1;
|
||||||
|
linuxvars.mouse_data.right_button = 0;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
case LeaveNotify: {
|
case EnterNotify: {
|
||||||
linuxvars.mouse_data.out_of_window = 1;
|
linuxvars.mouse_data.out_of_window = 0;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case FocusIn:
|
case LeaveNotify: {
|
||||||
case FocusOut: {
|
linuxvars.mouse_data.out_of_window = 1;
|
||||||
linuxvars.mouse_data.left_button = 0;
|
}break;
|
||||||
linuxvars.mouse_data.right_button = 0;
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case ConfigureNotify: {
|
case FocusIn:
|
||||||
i32 w = Event.xconfigure.width, h = Event.xconfigure.height;
|
case FocusOut: {
|
||||||
|
linuxvars.mouse_data.left_button = 0;
|
||||||
|
linuxvars.mouse_data.right_button = 0;
|
||||||
|
}break;
|
||||||
|
|
||||||
if(w != linuxvars.target.width || h != linuxvars.target.height){
|
case ConfigureNotify: {
|
||||||
LinuxResizeTarget(Event.xconfigure.width, Event.xconfigure.height);
|
i32 w = Event.xconfigure.width, h = Event.xconfigure.height;
|
||||||
}
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case MappingNotify: {
|
if(w != linuxvars.target.width || h != linuxvars.target.height){
|
||||||
if(Event.xmapping.request == MappingModifier || Event.xmapping.request == MappingKeyboard){
|
LinuxResizeTarget(Event.xconfigure.width, Event.xconfigure.height);
|
||||||
XRefreshKeyboardMapping(&Event.xmapping);
|
}
|
||||||
keycode_init(linuxvars.XDisplay, &linuxvars.key_codes);
|
}break;
|
||||||
}
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case ClientMessage: {
|
case MappingNotify: {
|
||||||
if ((Atom)Event.xclient.data.l[0] == WM_DELETE_WINDOW) {
|
if(Event.xmapping.request == MappingModifier || Event.xmapping.request == MappingKeyboard){
|
||||||
keep_running = false;
|
XRefreshKeyboardMapping(&Event.xmapping);
|
||||||
}
|
keycode_init(linuxvars.XDisplay, &linuxvars.key_codes);
|
||||||
}break;
|
}
|
||||||
}
|
}break;
|
||||||
|
|
||||||
PrevEvent = Event;
|
case ClientMessage: {
|
||||||
|
if ((Atom)Event.xclient.data.l[0] == WM_DELETE_WINDOW) {
|
||||||
|
keep_running = false;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
// NOTE(inso): Someone wants us to give them the clipboard data.
|
||||||
|
case SelectionRequest: {
|
||||||
|
XSelectionRequestEvent request = Event.xselectionrequest;
|
||||||
|
|
||||||
|
XSelectionEvent response = {};
|
||||||
|
response.type = SelectionNotify;
|
||||||
|
response.requestor = request.requestor;
|
||||||
|
response.selection = request.selection;
|
||||||
|
response.target = request.target;
|
||||||
|
response.time = request.time;
|
||||||
|
response.property = None;
|
||||||
|
|
||||||
|
//TODO(inso): handle TARGETS negotiation instead of requiring UTF8_STRING
|
||||||
|
if (
|
||||||
|
linuxvars.clipboard_outgoing.size &&
|
||||||
|
request.target == linuxvars.atom_UTF8_STRING &&
|
||||||
|
request.selection == linuxvars.atom_CLIPBOARD &&
|
||||||
|
request.property != None &&
|
||||||
|
request.display &&
|
||||||
|
request.requestor
|
||||||
|
){
|
||||||
|
XChangeProperty(
|
||||||
|
request.display,
|
||||||
|
request.requestor,
|
||||||
|
request.property,
|
||||||
|
request.target,
|
||||||
|
8,
|
||||||
|
PropModeReplace,
|
||||||
|
(unsigned char*)linuxvars.clipboard_outgoing.str,
|
||||||
|
linuxvars.clipboard_outgoing.size
|
||||||
|
);
|
||||||
|
|
||||||
|
response.property = request.property;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSendEvent(request.display, request.requestor, True, 0, (XEvent*)&response);
|
||||||
|
|
||||||
|
}break;
|
||||||
|
|
||||||
|
// NOTE(inso): Another program is now the clipboard owner.
|
||||||
|
case SelectionClear: {
|
||||||
|
if(Event.xselectionclear.selection == linuxvars.atom_CLIPBOARD){
|
||||||
|
linuxvars.clipboard_outgoing.size = 0;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
// NOTE(inso): A program is giving us the clipboard data we asked for.
|
||||||
|
case SelectionNotify: {
|
||||||
|
XSelectionEvent* e = (XSelectionEvent*)&Event;
|
||||||
|
if(
|
||||||
|
e->selection == linuxvars.atom_CLIPBOARD &&
|
||||||
|
e->target == linuxvars.atom_UTF8_STRING &&
|
||||||
|
e->property != None
|
||||||
|
){
|
||||||
|
Atom type;
|
||||||
|
int fmt;
|
||||||
|
unsigned long nitems, bytes_left;
|
||||||
|
u8 *data;
|
||||||
|
|
||||||
|
XGetWindowProperty(
|
||||||
|
linuxvars.XDisplay,
|
||||||
|
linuxvars.XWindow,
|
||||||
|
linuxvars.atom_CLIPBOARD,
|
||||||
|
0L,
|
||||||
|
LINUX_MAX_PASTE_CHARS/4L,
|
||||||
|
False,
|
||||||
|
linuxvars.atom_UTF8_STRING,
|
||||||
|
&type,
|
||||||
|
&fmt,
|
||||||
|
&nitems,
|
||||||
|
&bytes_left,
|
||||||
|
&data
|
||||||
|
);
|
||||||
|
|
||||||
|
LinuxStringDup(&linuxvars.clipboard_contents, data, nitems);
|
||||||
|
|
||||||
|
XFree(data);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 redraw = 1;
|
PrevEvent = Event;
|
||||||
|
|
||||||
Key_Input_Data input_data;
|
|
||||||
Mouse_State mouse;
|
|
||||||
Application_Step_Result result;
|
|
||||||
|
|
||||||
input_data = linuxvars.key_data;
|
|
||||||
mouse = linuxvars.mouse_data;
|
|
||||||
|
|
||||||
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
|
|
||||||
result.redraw = redraw;
|
|
||||||
result.lctrl_lalt_is_altgr = 0;
|
|
||||||
|
|
||||||
linuxvars.app.step(linuxvars.system,
|
|
||||||
&linuxvars.key_codes,
|
|
||||||
&input_data,
|
|
||||||
&mouse,
|
|
||||||
&linuxvars.target,
|
|
||||||
&memory_vars,
|
|
||||||
&exchange_vars,
|
|
||||||
linuxvars.clipboard_contents,
|
|
||||||
1, linuxvars.first, redraw,
|
|
||||||
&result);
|
|
||||||
|
|
||||||
if (result.redraw){
|
|
||||||
LinuxRedrawTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
linuxvars.key_data = {};
|
|
||||||
linuxvars.mouse_data.left_button_pressed = 0;
|
|
||||||
linuxvars.mouse_data.left_button_released = 0;
|
|
||||||
linuxvars.mouse_data.right_button_pressed = 0;
|
|
||||||
linuxvars.mouse_data.right_button_released = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(inso): is getting the clipboard every frame a bad idea?
|
||||||
|
XConvertSelection(
|
||||||
|
linuxvars.XDisplay,
|
||||||
|
linuxvars.atom_CLIPBOARD,
|
||||||
|
linuxvars.atom_UTF8_STRING,
|
||||||
|
linuxvars.atom_CLIPBOARD,
|
||||||
|
linuxvars.XWindow,
|
||||||
|
CurrentTime
|
||||||
|
);
|
||||||
|
|
||||||
|
b32 redraw = 1;
|
||||||
|
|
||||||
|
Key_Input_Data input_data;
|
||||||
|
Mouse_State mouse;
|
||||||
|
Application_Step_Result result;
|
||||||
|
|
||||||
|
input_data = linuxvars.key_data;
|
||||||
|
mouse = linuxvars.mouse_data;
|
||||||
|
|
||||||
|
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
|
||||||
|
result.redraw = redraw;
|
||||||
|
result.lctrl_lalt_is_altgr = 0;
|
||||||
|
|
||||||
|
linuxvars.app.step(linuxvars.system,
|
||||||
|
&linuxvars.key_codes,
|
||||||
|
&input_data,
|
||||||
|
&mouse,
|
||||||
|
&linuxvars.target,
|
||||||
|
&memory_vars,
|
||||||
|
&exchange_vars,
|
||||||
|
linuxvars.clipboard_contents,
|
||||||
|
1, linuxvars.first, redraw,
|
||||||
|
&result);
|
||||||
|
|
||||||
|
if (result.redraw){
|
||||||
|
LinuxRedrawTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
linuxvars.key_data = {};
|
||||||
|
linuxvars.mouse_data.left_button_pressed = 0;
|
||||||
|
linuxvars.mouse_data.left_button_released = 0;
|
||||||
|
linuxvars.mouse_data.right_button_pressed = 0;
|
||||||
|
linuxvars.mouse_data.right_button_released = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue