implement random playback
[uwplayer.git] / application / main.c
index 85687c5..ecaf72b 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <locale.h>
+#include <time.h>
+#include <inttypes.h>
+#include <sys/stat.h>
 
 #include "window.h"
+#include "main.h"
+#include "settings.h"
 
 #include <ucx/buffer.h>
 #include <ucx/utils.h>
 
-#define APP_NAME "MediaPlayer"
-
 static XtAppContext app;
 static Display *display;
+static Widget toplevel_window;
+
+static char *open_file_arg;
+
+static int event_pipe[2];
 
 static String fallback[] = {
         "*renderTable: rt",
         "*rt*fontType: FONT_IS_XFT",
         "*rt*fontName: Sans",
         "*rt*fontSize: 9",
+        
+        "*pbbutton.shadowThickness: 1",
+        "*pbbutton.highlightThickness: 1",
+    
+        "*XmText.baseTranslations: #override\\n" \
+                                "Ctrl~Alt~Meta<KeyPress>v: paste-clipboard()\\n" \
+                                "Ctrl~Alt~Meta<KeyPress>c: copy-clipboard()\\n" \
+                                "Ctrl~Alt~Meta<KeyPress>x: cut-clipboard()\\n" \
+                                "Ctrl~Alt~Meta<KeyPress>u: delete-to-start-of-line()\\n",
+        "*XmTextField.baseTranslations: #override\\n" \
+                                "Ctrl~Alt~Meta<KeyPress>v: paste-clipboard()\\n" \
+                                "Ctrl~Alt~Meta<KeyPress>c: copy-clipboard()\\n" \
+                                "Ctrl~Alt~Meta<KeyPress>x: cut-clipboard()\\n" \
+                                "Ctrl~Alt~Meta<KeyPress>u: delete-to-start-of-line()\\n",
        NULL
 };
 
-int main(int argc, char** argv) { 
+static String langProc(Display *dp, String xnl, XtPointer closure) {
+    setlocale(LC_ALL, xnl);
+    setlocale(LC_NUMERIC, "C");
+    return setlocale(LC_ALL, NULL);
+}
+
+typedef struct EventLoopCB {
+    XtWorkProc proc;
+    XtPointer data;
+} EventLoopCB;
+
+static void input_proc(XtPointer data, int *source, XtInputId *iid) {
+    EventLoopCB cb[16];
+    ssize_t r = read(event_pipe[0], cb, sizeof(EventLoopCB)*16);
+    size_t n = r / sizeof(EventLoopCB);
+    for(int i=0;i<n;i++) {
+        cb[i].proc(cb[i].data);
+    }
+}
+
+int main(int argc, char** argv) {  
     // disable stdout buffering, because the netbeans's internal terminal
     // has a bug on freebsd and doesn't flush the output after a newline
     setvbuf(stdout, NULL, _IONBF, 0);
     
+    // init event pipe for xt event loop
+    if(pipe(event_pipe)) {
+        perror("pipe");
+        return 2;
+    }
+     
+    // initialize toolkit
     XtToolkitInitialize();
-    XtSetLanguageProc(NULL, NULL, NULL);
+    XtSetLanguageProc(NULL, langProc, NULL);
     app = XtCreateApplicationContext();
     XtAppSetFallbackResources(app, fallback);
+       
+    display =  XtOpenDisplay(app, NULL, APP_NAME, APP_CLASS, NULL, 0, &argc, argv);
     
-    display =  XtOpenDisplay(app, NULL, APP_NAME, APP_NAME, NULL, 0, &argc, argv);
+    if(argc > 1) {
+        struct stat s;
+        if(stat(argv[1], &s)) {
+            fprintf(stderr, "Cannot open file: %s\n", argv[1]);
+            perror("");
+            return 1;
+        }
+        open_file_arg = argv[1];
+    }
     
+    XtAppAddInput(
+            app,
+            event_pipe[0],
+            (XtPointer)XtInputReadMask,
+            input_proc,
+            NULL);
+    
+    // load settings
+    if(load_config()) {
+        return 1;
+    }
+   
     MainWindow *window = WindowCreate(display);
+    toplevel_window = window->window;
+    
+    // random numbers used for creating tmp dirs and for random playback
+    srand(time(NULL));
     
     WindowShow(window);
-    XtAppMainLoop(app);
+    AppMainLoop(app);
     
     return 0;
 }
@@ -69,3 +145,40 @@ XtAppContext* GetAppContext(void) {
 void ApplicationExit(void) {
     XtAppSetExitFlag(app);
 }
+
+void AppExecProc(XtWorkProc proc, XtPointer data) {
+    EventLoopCB cb;
+    cb.proc = proc;
+    cb.data = data;
+    write(event_pipe[1], &cb, sizeof(cb));
+}
+
+char* GetOpenFileArg(void) {
+    return open_file_arg;
+}
+
+void CleanOpenFileArg(void) {
+    open_file_arg = NULL;
+}
+
+static Window app_player_window = 0;
+
+void SetPlayerWindow(Window w) {
+    app_player_window = w;
+}
+
+/*
+ * Extended Xt main loop, that also handles external window events
+ */
+void AppMainLoop(XtAppContext app) {
+    while(!XtAppGetExitFlag(app)) {
+        XEvent event;
+        XtAppNextEvent(app, &event);
+        
+        if(app_player_window != 0 && event.xany.window == app_player_window) {
+            WindowHandlePlayerEvent(GetMainWindow(), &event);
+        } else {
+            XtDispatchEvent(&event);
+        }
+    }
+}