summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2024-03-08 20:48:05 +0100
committerAldrik Ramaekers <aldrikboy@gmail.com>2024-03-08 20:48:05 +0100
commit0b429e06b8c4b66a9f7fe89b5504315ab4f69616 (patch)
treed5cf9d15d8790559f0c4b006ede0ca1314639077 /src
parentdef620a66bc5b0dc1107102f2c234888dc9bd830 (diff)
linux building
Diffstat (limited to 'src')
-rw-r--r--src/array.cpp3
-rw-r--r--src/config.cpp8
-rw-r--r--src/image.cpp4
-rw-r--r--src/image.h14
-rw-r--r--src/linux/main_linux.cpp296
-rw-r--r--src/linux/mutex.cpp129
-rw-r--r--src/memory_bucket.cpp1
-rw-r--r--src/mutex.h23
-rw-r--r--src/platform.h1
-rw-r--r--src/windows/main_windows.cpp (renamed from src/main_windows.cpp)8
-rw-r--r--src/windows/mutex.cpp (renamed from src/mutex.cpp)4
11 files changed, 476 insertions, 15 deletions
diff --git a/src/array.cpp b/src/array.cpp
index 38b7095..a0b5863 100644
--- a/src/array.cpp
+++ b/src/array.cpp
@@ -1,5 +1,8 @@
#include "array.h"
+#include <stdlib.h>
+#include <cstring>
+
ts_array ts_array_create(int entry_size)
{
ts_array new_ts_array;
diff --git a/src/config.cpp b/src/config.cpp
index 4813c5c..216c93d 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -3,6 +3,8 @@
#include "search.h"
#include <stdio.h>
+#include <string.h>
+#include <cstring>
utf8_int8_t path_buffer[MAX_INPUT_LENGTH];
utf8_int8_t filter_buffer[MAX_INPUT_LENGTH];
@@ -19,9 +21,9 @@ static void _ts_config_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entr
int threads, maxSize;
- if (sscanf(line, "Path=%s", &path) == 1) { strcpy_s(path_buffer, MAX_INPUT_LENGTH, (char*)path); }
- else if (sscanf(line, "Filter=%s", &filter) == 1) { strcpy_s(filter_buffer, MAX_INPUT_LENGTH, (char*)filter); }
- else if (sscanf(line, "Query=%s", &query) == 1) { strcpy_s(query_buffer, MAX_INPUT_LENGTH, (char*)query); }
+ if (sscanf(line, "Path=%s", &path) == 1) { strcpy(path_buffer, (char*)path); }
+ else if (sscanf(line, "Filter=%s", &filter) == 1) { strcpy(filter_buffer, (char*)filter); }
+ else if (sscanf(line, "Query=%s", &query) == 1) { strcpy(query_buffer, (char*)query); }
else if (sscanf(line, "Threads=%d", &threads) == 1) { ts_thread_count = threads; }
else if (sscanf(line, "MaxSize=%d", &maxSize) == 1) { max_file_size = maxSize; }
}
diff --git a/src/image.cpp b/src/image.cpp
index ba67859..0755055 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -71,8 +71,8 @@ void ts_load_images() {
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
//glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
diff --git a/src/image.h b/src/image.h
index 21f3438..860c767 100644
--- a/src/image.h
+++ b/src/image.h
@@ -1,6 +1,7 @@
#ifndef INCLUDE_IMAGE
#define INCLUDE_IMAGE
+#if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
@@ -13,6 +14,19 @@ typedef struct t_ts_image {
int width;
int height;
} ts_image;
+#elif defined(__linux__)
+
+//#include <GL/glut.h>
+#include "imgui.h"
+#include "imgui_impl_opengl3_loader.h"
+#include "imgui_impl_opengl3.h"
+
+typedef struct t_ts_image {
+ GLuint id;
+ int width;
+ int height;
+} ts_image;
+#endif
extern ts_image img_logo;
extern ts_image img_search;
diff --git a/src/linux/main_linux.cpp b/src/linux/main_linux.cpp
new file mode 100644
index 0000000..f1fc01d
--- /dev/null
+++ b/src/linux/main_linux.cpp
@@ -0,0 +1,296 @@
+#include "imgui.h"
+#include "imgui_spectrum.h"
+#include "imgui_impl_glfw.h"
+#include "imgui_impl_opengl3.h"
+#include "../utf8.h"
+#include "platform.h"
+#include "mutex.h"
+#include "array.h"
+#include "memory_bucket.h"
+#include "image.h"
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#define GL_SILENCE_DEPRECATION
+#if defined(IMGUI_IMPL_OPENGL_ES2)
+#include <GLES2/gl2.h>
+#endif
+#include <GLFW/glfw3.h> // Will drag system OpenGL headers
+
+void ts_create_gui(int window_w, int window_h);
+void ts_load_images();
+void ts_init();
+
+bool program_running = true;
+
+char config_path[MAX_INPUT_LENGTH];
+static const char* _ts_platform_get_config_file_path(char* buffer) {
+ char *env = getenv("HOME");
+ snprintf(buffer, MAX_INPUT_LENGTH, "%s%s", env, "text-search/imgui.ini");
+ return buffer;
+}
+
+static void glfw_error_callback(int error, const char* description)
+{
+ fprintf(stderr, "GLFW Error %d: %s\n", error, description);
+}
+
+// Main code
+int main(int, char**)
+{
+ glfwSetErrorCallback(glfw_error_callback);
+ if (!glfwInit())
+ return 1;
+
+ // Decide GL+GLSL versions
+#if defined(IMGUI_IMPL_OPENGL_ES2)
+ // GL ES 2.0 + GLSL 100
+ const char* glsl_version = "#version 100";
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
+#elif defined(__APPLE__)
+ // GL 3.2 + GLSL 150
+ const char* glsl_version = "#version 150";
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
+ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
+#else
+ // GL 3.0 + GLSL 130
+ const char* glsl_version = "#version 130";
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
+ //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
+ //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only
+#endif
+
+ // Create window with graphics context
+ GLFWwindow* window = glfwCreateWindow(1280, 720, "Text-Search", nullptr, nullptr);
+ if (window == nullptr)
+ return 1;
+ glfwMakeContextCurrent(window);
+ glfwSwapInterval(1); // Enable vsync
+
+ IMGUI_CHECKVERSION();
+ ImGui::CreateContext();
+ ImGuiIO& io = ImGui::GetIO(); (void)io;
+ io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
+ io.IniFilename = _ts_platform_get_config_file_path(config_path);
+
+ // Setup Platform/Renderer backends
+ ImGui_ImplGlfw_InitForOpenGL(window, true);
+ ImGui_ImplOpenGL3_Init(glsl_version);
+
+ // Setup Dear ImGui style
+ ImGui::Spectrum::StyleColorsSpectrum();
+ //ImGui::Spectrum::LoadFont(18.0f);
+
+ ts_init();
+ ts_load_images();
+ ts_load_config();
+
+ ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
+ int display_w, display_h;
+ while (!glfwWindowShouldClose(window))
+ {
+ glfwPollEvents();
+
+ // Start the Dear ImGui frame
+ ImGui_ImplOpenGL3_NewFrame();
+ ImGui_ImplGlfw_NewFrame();
+ ImGui::NewFrame();
+
+ ts_create_gui(display_w, display_h);
+
+ // Rendering
+ ImGui::Render();
+ glfwGetFramebufferSize(window, &display_w, &display_h);
+ glViewport(0, 0, display_w, display_h);
+ glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
+ glClear(GL_COLOR_BUFFER_BIT);
+ ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
+
+ glfwSwapBuffers(window);
+ }
+
+ // Cleanup
+ ImGui_ImplOpenGL3_Shutdown();
+ ImGui_ImplGlfw_Shutdown();
+ ImGui::DestroyContext();
+
+ glfwDestroyWindow(window);
+ glfwTerminate();
+
+ return 0;
+}
+
+bool ts_platform_dir_exists(utf8_int8_t* path) {
+ DIR* dir = opendir(path);
+ if (dir) {
+ /* Directory exists. */
+ closedir(dir);
+ return true;
+ } else if (ENOENT == errno) {
+ return false; // does not exist
+ } else {
+ return false; // error opening dir
+ }
+}
+
+ts_file_content ts_platform_read_file(char *path, const char *mode) {
+ ts_file_content result;
+ result.content = 0;
+ result.content_length = 0;
+ result.file_error = 0;
+
+ FILE *file = fopen(path, mode);
+
+ if (!file)
+ {
+ if (errno == EMFILE)
+ result.file_error = FILE_ERROR_TOO_MANY_OPEN_FILES_PROCESS;
+ else if (errno == ENFILE)
+ result.file_error = FILE_ERROR_TOO_MANY_OPEN_FILES_SYSTEM;
+ else if (errno == EACCES)
+ result.file_error = FILE_ERROR_NO_ACCESS;
+ else if (errno == EPERM)
+ result.file_error = FILE_ERROR_NO_ACCESS;
+ else if (errno == ENOENT)
+ result.file_error = FILE_ERROR_NOT_FOUND;
+ else if (errno == ECONNABORTED)
+ result.file_error = FILE_ERROR_CONNECTION_ABORTED;
+ else if (errno == ECONNREFUSED)
+ result.file_error = FILE_ERROR_CONNECTION_REFUSED;
+ else if (errno == ENETDOWN)
+ result.file_error = FILE_ERROR_NETWORK_DOWN;
+ else if (errno == EREMOTEIO)
+ result.file_error = FILE_ERROR_REMOTE_IO_ERROR;
+ else if (errno == ESTALE)
+ result.file_error = FILE_ERROR_STALE;
+ else
+ {
+ result.file_error = FILE_ERROR_GENERIC;
+ }
+
+ return result;
+ }
+
+ fseek(file, 0 , SEEK_END);
+ int length = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ int length_to_alloc = length+1;
+
+ result.content = malloc(length_to_alloc);
+ if (!result.content) {
+ fclose(file);
+ return result;
+ }
+
+ memset(result.content, 0, length);
+ int read_result = fread(result.content, 1, length, file);
+ if (read_result == 0 && length != 0)
+ {
+ free(result.content);
+ result.content = 0;
+ return result;
+ }
+
+ result.content_length = read_result;
+
+ ((char*)result.content)[length] = 0;
+
+ fclose(file);
+ return result;
+}
+
+void ts_platform_list_files_block(ts_search_result* result, wchar_t* start_dir) {
+
+ utf8_int8_t* search_dir = (utf8_int8_t*)ts_memory_bucket_reserve(&result->memory, MAX_INPUT_LENGTH);
+ if (start_dir == nullptr) {
+ strcpy(search_dir, result->directory_to_search);
+ }
+ else {
+ strcpy(search_dir, (char*)start_dir);
+ }
+
+ // Append wildcard
+ utf8_int8_t* search_dir_fix = (utf8_int8_t*)ts_memory_bucket_reserve(&result->memory, MAX_INPUT_LENGTH);
+ strcpy(search_dir_fix, search_dir);
+ strcat(search_dir_fix, u8"/*");
+
+ DIR *d;
+ struct dirent *dir;
+ d = opendir(search_dir);
+ if (d) {
+ chdir(search_dir);
+ while ((dir = readdir(d)) != NULL) {
+ if (result->cancel_search) return;
+ chdir(search_dir);
+
+ if (dir->d_type == DT_DIR)
+ {
+ if ((strcmp(dir->d_name, ".") == 0) || (strcmp(dir->d_name, "..") == 0))
+ continue;
+
+ utf8_int8_t complete_file_path[MAX_INPUT_LENGTH];
+ strcpy(complete_file_path, search_dir);
+ strcat(complete_file_path, "/");
+ strcat(complete_file_path, dir->d_name);
+
+ // do recursive search
+ ts_platform_list_files_block(result, (wchar_t*)complete_file_path);
+ }
+ // we handle DT_UNKNOWN for file systems that do not support type lookup.
+ else if (dir->d_type == DT_REG || dir->d_type == DT_UNKNOWN)
+ {
+ char *matched_filter = 0;
+ if (ts_filter_matches(&result->filters, dir->d_name, &matched_filter) == -1) {
+ continue;
+ }
+ (void)matched_filter;
+
+
+ utf8_int8_t complete_file_path[MAX_INPUT_LENGTH];
+ strcpy(complete_file_path, search_dir);
+ strcat(complete_file_path, "/");
+ strcat(complete_file_path, dir->d_name);
+
+ ts_found_file* f = (ts_found_file*)ts_memory_bucket_reserve(&result->memory, sizeof(ts_found_file));
+ f->path = (utf8_int8_t*)ts_memory_bucket_reserve(&result->memory, MAX_INPUT_LENGTH);
+ f->match_count = 0;
+ f->error = 0;
+ strcpy(f->path, complete_file_path);
+
+ ts_mutex_lock(&result->files.mutex);
+ ts_array_push_size(&result->files, &f, sizeof(ts_found_file*));
+ ts_mutex_unlock(&result->files.mutex);
+ }
+ }
+ closedir(d);
+ }
+}
+
+uint64_t ts_platform_get_time(uint64_t compare) {
+ struct timespec tms;
+ if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&tms)) {
+ return -1;
+ }
+ long result = 0;
+ result = tms.tv_sec * 1000000;
+ result += tms.tv_nsec/1000;
+ if (tms.tv_nsec % 1000 >= 500) {
+ ++result;
+ }
+
+ if (compare != 0) {
+ return result - compare;
+ }
+
+ return result;
+}
diff --git a/src/linux/mutex.cpp b/src/linux/mutex.cpp
new file mode 100644
index 0000000..f59a1eb
--- /dev/null
+++ b/src/linux/mutex.cpp
@@ -0,0 +1,129 @@
+#include "mutex.h"
+
+extern long int syscall (long int __sysno, ...);
+extern int pthread_tryjoin_np(pthread_t ts_thread, void **retval);
+
+ts_thread ts_thread_start(void *(*start_routine) (void *), void *arg)
+{
+ ts_thread result;
+ result.valid = false;
+
+ pthread_attr_t attr;
+ int attr_init_result = pthread_attr_init(&attr);
+ if (attr_init_result)
+ return result;
+
+ int start_thread_result = pthread_create(&result.thread, &attr, start_routine, arg);
+ if (start_thread_result)
+ {
+ pthread_attr_destroy(&attr);
+ return result;
+ }
+
+ result.valid = true;
+ pthread_attr_destroy(&attr);
+
+ return result;
+}
+
+void ts_thread_detach(ts_thread *ts_thread)
+{
+ if (ts_thread->valid)
+ {
+ pthread_detach(ts_thread->thread);
+ }
+}
+
+void ts_thread_join(ts_thread *ts_thread)
+{
+ if (ts_thread->valid)
+ {
+ void *retval;
+ pthread_join(ts_thread->thread, &retval);
+ }
+}
+
+bool ts_thread_tryjoin(ts_thread *ts_thread)
+{
+ if (ts_thread->valid)
+ {
+ void *retval;
+ bool thread_joined = !pthread_tryjoin_np(ts_thread->thread, &retval);
+ return thread_joined;
+ }
+ return false;
+}
+
+void ts_thread_exit()
+{
+ pthread_exit(0);
+}
+
+void ts_thread_stop(ts_thread *ts_thread)
+{
+ if (ts_thread->valid)
+ {
+ pthread_cancel(ts_thread->thread);
+ }
+}
+
+ts_mutex ts_mutex_create()
+{
+ ts_mutex result;
+
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
+
+ pthread_mutex_init(&result.mutex, &attr);
+
+ pthread_mutexattr_destroy(&attr);
+
+ return result;
+}
+
+ts_mutex ts_mutex_create_recursive()
+{
+ ts_mutex result;
+
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(&result.mutex, &attr);
+
+ pthread_mutexattr_destroy(&attr);
+
+ return result;
+}
+
+void ts_mutex_lock(ts_mutex *ts_mutex)
+{
+ pthread_mutex_lock(&ts_mutex->mutex);
+}
+
+bool ts_mutex_trylock(ts_mutex *ts_mutex)
+{
+ return !pthread_mutex_trylock(&ts_mutex->mutex);
+}
+
+void ts_mutex_unlock(ts_mutex *ts_mutex)
+{
+ pthread_mutex_unlock(&ts_mutex->mutex);
+}
+
+void ts_mutex_destroy(ts_mutex *ts_mutex)
+{
+ ts_mutex_unlock(ts_mutex);
+ pthread_mutex_destroy(&ts_mutex->mutex);
+}
+
+int ts_thread_get_id()
+{
+ return (int)syscall(__NR_gettid);
+}
+
+void ts_thread_sleep(int microseconds)
+{
+ usleep(microseconds);
+} \ No newline at end of file
diff --git a/src/memory_bucket.cpp b/src/memory_bucket.cpp
index 0d163d0..1a1e54d 100644
--- a/src/memory_bucket.cpp
+++ b/src/memory_bucket.cpp
@@ -1,4 +1,5 @@
#include "memory_bucket.h"
+#include <stdlib.h>
ts_memory_bucket ts_memory_bucket_init(int bucket_size)
{
diff --git a/src/mutex.h b/src/mutex.h
index a745947..8499bcc 100644
--- a/src/mutex.h
+++ b/src/mutex.h
@@ -1,7 +1,7 @@
#ifndef INCLUDE_MUTEX
#define INCLUDE_MUTEX
-#ifdef _WIN32
+#if defined(_WIN32)
#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include <stddef.h>
@@ -19,11 +19,28 @@ typedef struct t_ts_thread
HANDLE thread;
int valid;
} ts_thread;
+
+#elif defined(__linux__)
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+
+typedef struct t_ts_thread
+{
+ pthread_t thread;
+ bool valid;
+} ts_thread;
+
+typedef struct t_ts_mutex
+{
+ pthread_mutex_t mutex;
+} ts_mutex;
#endif
ts_thread ts_thread_start(void *(*start_routine) (void *), void *arg);
void ts_thread_join(ts_thread *ts_thread);
-int ts_thread_tryjoin(ts_thread *ts_thread);
+bool ts_thread_tryjoin(ts_thread *ts_thread);
void ts_thread_detach(ts_thread *ts_thread);
void ts_thread_stop(ts_thread *ts_thread);
int ts_thread_get_id();
@@ -33,7 +50,7 @@ void ts_thread_exit();
ts_mutex ts_mutex_create_recursive();
ts_mutex ts_mutex_create();
void ts_mutex_lock(ts_mutex *ts_mutex);
-int ts_mutex_trylock(ts_mutex *ts_mutex);
+bool ts_mutex_trylock(ts_mutex *ts_mutex);
void ts_mutex_unlock(ts_mutex *ts_mutex);
void ts_mutex_destroy(ts_mutex *ts_mutex);
diff --git a/src/platform.h b/src/platform.h
index 7fdc15a..b9a9e9c 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -34,7 +34,6 @@ extern bool program_running;
bool ts_platform_dir_exists(utf8_int8_t* dir);
ts_file_content ts_platform_read_file(char *path, const char *mode);
void ts_platform_list_files_block(ts_search_result* result, wchar_t* start_dir = nullptr);
-void ts_platform_list_files(ts_search_result* result);
uint64_t ts_platform_get_time(uint64_t compare = 0); // if compare is not 0, return difference between timestamp and now, in milliseconds.
#endif \ No newline at end of file
diff --git a/src/main_windows.cpp b/src/windows/main_windows.cpp
index 4410f12..cb59d9d 100644
--- a/src/main_windows.cpp
+++ b/src/windows/main_windows.cpp
@@ -1,9 +1,9 @@
#include <stdio.h>
-#include "../imgui/imgui.h"
-#include "../imgui/imgui_spectrum.h"
-#include "../imgui/imgui_impl_opengl3.h"
-#include "../imgui/imgui_impl_win32.h"
+#include "imgui.h"
+#include "imgui_spectrum.h"
+#include "imgui_impl_opengl3.h"
+#include "imgui_impl_win32.h"
#include "../utf8.h"
#include "platform.h"
#include "mutex.h"
diff --git a/src/mutex.cpp b/src/windows/mutex.cpp
index f224312..47663cd 100644
--- a/src/mutex.cpp
+++ b/src/windows/mutex.cpp
@@ -23,7 +23,7 @@ void ts_mutex_lock(ts_mutex *ts_mutex)
INFINITE); // no time-out interval
}
-int ts_mutex_trylock(ts_mutex *ts_mutex)
+bool ts_mutex_trylock(ts_mutex *ts_mutex)
{
return WaitForSingleObject(ts_mutex->mutex, 1) == WAIT_OBJECT_0;
}
@@ -60,7 +60,7 @@ void ts_thread_join(ts_thread *ts_thread)
}
}
-int ts_thread_tryjoin(ts_thread *ts_thread)
+bool ts_thread_tryjoin(ts_thread *ts_thread)
{
if (ts_thread->valid)
{