root/applications/osmophone/main.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. recompute_res
  2. set_status
  3. update_state_info
  4. cbk_on_progress
  5. set_full_screen
  6. on_gpac_rti_log
  7. on_gpac_log
  8. setup_logs
  9. do_open_file
  10. switch_playlist
  11. GPAC_EventProc
  12. LoadTerminal
  13. do_layout
  14. set_backlight_state
  15. gf_freeze_display
  16. show_taskbar
  17. refresh_recent_files
  18. open_file
  19. load_recent_file
  20. AboutDialogProc
  21. view_about
  22. pause_file
  23. set_svg_progressive
  24. set_gx_mode
  25. do_copy_paste
  26. rewrite_log_tools
  27. HandleCommand
  28. OnMenuPopup
  29. MainWndProc
  30. InitInstance
  31. WinMain

/*
 *                      GPAC - Multimedia Framework C SDK
 *
 *                      Authors: Jean Le Feuvre
 *                      Copyright (c) Telecom ParisTech 2000-2012
 *                                      All rights reserved
 *
 *  This file is part of GPAC / command-line client
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/*includes both terminal and od browser*/
#include <gpac/terminal.h>
#include <gpac/options.h>
/*for initial setup*/
#include <gpac/modules/service.h>

#include <gpac/internal/terminal_dev.h>
#include <gpac/internal/compositor_dev.h>

#include <windows.h>
#include <commdlg.h>
#include <commctrl.h>

#ifdef _WIN32_WCE
#include <aygshell.h>
#include <gx.h>

#else

#ifndef _T
#define _T(__a) (LPCSTR) __a
#endif

#endif

#include "resource.h"

#define WM_LOADTERM     WM_USER + 1
#define STATE_TIMER_ID          20
#define STATE_TIMER_DUR         1000
#define GPAC_TIMER_ID           21
#define GPAC_TIMER_DUR          33


Bool gf_file_dialog(HINSTANCE inst, HWND parent, char *url, const char *ext_list, GF_Config *cfg);
void set_backlight_state(Bool disable);
void refresh_recent_files();
void do_layout(Bool notif_size);

static HWND g_hwnd = NULL;
static HWND g_hwnd_disp = NULL;
static HWND g_hwnd_menu = NULL;
static HWND g_hwnd_status = NULL;
static HINSTANCE g_hinst = NULL;
static Bool is_ppc = GF_FALSE;

static Bool is_connected = GF_FALSE;
static Bool navigation_on = GF_FALSE;
static Bool playlist_navigation_on = GF_TRUE;

static u32 log_level = GF_LOG_ERROR;

static u32 Duration;
static Bool CanSeek = GF_FALSE;
static u32 Volume=100;
static char the_url[GF_MAX_PATH] = "";
static Bool NavigateTo = GF_FALSE;
static char the_next_url[GF_MAX_PATH];
static GF_Terminal *term;
static GF_User user;
static u32 disp_w = 0;
static u32 disp_h = 0;
static u32 screen_w = 0;
static u32 screen_h = 0;
static u32 menu_h = 0;
static u32 caption_h = 0;
static u32 ratio_h = 1;
static Bool backlight_off = GF_FALSE;
static u32 prev_batt_bl, prev_ac_bl;
static Bool show_status = GF_TRUE;
static Bool reset_status = GF_TRUE;
static u32 last_state_time = 0;
static Bool loop = GF_FALSE;
static Bool full_screen = GF_FALSE;
static Bool force_2d_gl = GF_FALSE;
static Bool ctrl_mod_down = GF_FALSE;
static Bool view_cpu = GF_TRUE;
static Bool use_low_fps = GF_FALSE;
static Bool use_svg_prog = GF_FALSE;

static Bool log_rti = GF_FALSE;
static FILE *log_file = NULL;
static u32 rti_update_time_ms = 200;

static u32 playlist_act = 0;


void recompute_res(u32 sw, u32 sh )
{
        caption_h = GetSystemMetrics(SM_CYCAPTION);
        menu_h = GetSystemMetrics(SM_CYMENU)+2;
        screen_w = GetSystemMetrics(SM_CXSCREEN);
        screen_h = GetSystemMetrics(SM_CYSCREEN);

        ratio_h = sh / screen_h;
        screen_w = sw;
        screen_h = sh;
        menu_h *= ratio_h;
//      caption_h *= ratio_h;
        disp_w = screen_w;
        disp_h = screen_h - menu_h /*- caption_h*/;
}


void set_status(char *state)
{
        if (show_status && g_hwnd_status) {
#ifdef _WIN32_WCE
                TCHAR wstate[1024];
                CE_CharToWide(state, (u16 *) wstate);
                SendMessage(g_hwnd_status, WM_SETTEXT, 0, (LPARAM) wstate);
#else
                SendMessage(g_hwnd_status, WM_SETTEXT, 0, (LPARAM) state);
#endif
                last_state_time = GetTickCount();
        }
}

void update_state_info()
{
        TCHAR wstate[1024];
        Double FPS;
        u32 time, m, s;
        if (!show_status) return;
        if (last_state_time) {
                if (GetTickCount() > last_state_time + 200) {
                        last_state_time = 0;
                        reset_status = GF_TRUE;
                }
                else return;
        }
        if (!term) return;
        if (!is_connected && reset_status) {
                SendMessage(g_hwnd_status, WM_SETTEXT, 0, (LPARAM) TEXT("Ready") );
                reset_status = GF_FALSE;
                return;
        }

        FPS = gf_term_get_framerate(term, GF_FALSE);
        time = gf_term_get_time_in_ms(term) / 1000;
        m = time/60;
        s = time - m*60;
        if (view_cpu) {
                GF_SystemRTInfo rti;
                if (!gf_sys_get_rti(STATE_TIMER_DUR, &rti, 0)) return;
                wsprintf(wstate, TEXT("T %02d:%02d : FPS %02.2f : CPU %02d"), m, s, FPS, rti.total_cpu_usage);
        } else {
                wsprintf(wstate, TEXT("T %02d:%02d : FPS %02.2f"), m, s, FPS);
        }
        SendMessage(g_hwnd_status, WM_SETTEXT, 0, (LPARAM) wstate);
}


static u64 prev_pos = 0;
void cbk_on_progress(void *_title, u64 done, u64 total)
{
#if 0
        char szMsg[1024];
        u32 pos = (u32) ((u64) done * 100)/total;
        if (pos<prev_pos) prev_pos = 0;
        if (pos!=prev_pos) {
                prev_pos = pos;
                sprintf(szMsg, "%s: (%02d/100)", _title ? (char *)_title : "", pos);
                set_status(szMsg);
        }
#endif
}

void set_full_screen()
{
        full_screen = (Bool)!full_screen;
        if (full_screen) {
                show_status = GF_FALSE;
                do_layout(GF_FALSE);
                gf_term_set_option(term, GF_OPT_FULLSCREEN, full_screen);
        } else {
                const char *str = gf_cfg_get_key(user.config, "General", "ShowStatusBar");
                show_status = (str && !strcmp(str, "yes")) ? GF_TRUE : GF_FALSE;
                gf_term_set_option(term, GF_OPT_FULLSCREEN, full_screen);
                do_layout(GF_TRUE);
        }
}


static void on_gpac_rti_log(void *cbk, GF_LOG_Level ll, GF_LOG_Tool lm, const char *fmt, va_list list)
{
        if (!log_file) return;

        if (lm & GF_LOG_RTI) {
                GF_SystemRTInfo rti;
                if (fmt) vfprintf(log_file, fmt, list);

                gf_sys_get_rti(rti_update_time_ms, &rti, 0);

                fprintf(log_file, "% 8d\t% 8d\t% 8d\t% 4d\t% 8d\t\t",
                        gf_sys_clock(),
                        gf_term_get_time_in_ms(term),
                        rti.total_cpu_usage,
                        (u32) gf_term_get_framerate(term, GF_FALSE),
                        (u32) ( rti.gpac_memory / 1024)
                       );
        } else if (fmt && (ll>=GF_LOG_INFO)) {
                vfprintf(log_file, fmt, list);
        }
}
static void on_gpac_log(void *cbk, GF_LOG_Level ll, GF_LOG_Tool lm, const char *fmt, va_list list)
{
        if (fmt && log_file) vfprintf(log_file, fmt, list);
}


static void setup_logs()
{
        if (log_file) gf_fclose(log_file);
        log_file = NULL;

        gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR);
        gf_log_set_callback(NULL, NULL);

        if (log_rti) {
                const char *filename = gf_cfg_get_key(user.config, "General", "LogFile");
                if (!filename) {
                        gf_cfg_set_key(user.config, "General", "LogFile", "\\gpac_logs.txt");
                        filename = "\\gpac_logs.txt";
                }
                log_file = gf_fopen(filename, "a+t");

                fprintf(log_file, "!! GPAC RunTime Info for file %s !!\n", the_url);
                fprintf(log_file, "SysTime(ms)\tSceneTime(ms)\tCPU\tFPS\tMemory(kB)\tObservation\n");

                gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR);
                gf_log_set_tool_level(GF_LOG_RTI, GF_LOG_DEBUG);
                gf_log_set_callback(log_file, on_gpac_rti_log);

                GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI] System state when enabling log\n"));
        } else {
                const char *filename = gf_cfg_get_key(user.config, "General", "LogFile");
                if (!filename) {
                        gf_cfg_set_key(user.config, "General", "LogFile", "\\gpac_logs.txt");
                        filename = "\\gpac_logs.txt";
                }
                const char *logs = gf_cfg_get_key(user.config, "General", "Logs");
                if (logs) {
                        if (gf_log_set_tools_levels( logs ) != GF_OK) {
                        } else {
                                if (log_file = gf_fopen(filename, "a+t")) {
                                        gf_log_set_callback(log_file, on_gpac_log);
                                }
                        }
                }
        }
}

void do_open_file()
{
        gf_cfg_set_key(user.config, "RecentFiles", the_url, NULL);
        gf_cfg_insert_key(user.config, "RecentFiles", the_url, "", 0);
        u32 count = gf_cfg_get_key_count(user.config, "RecentFiles");
        if (count > 10) gf_cfg_set_key(user.config, "RecentFiles", gf_cfg_get_key_name(user.config, "RecentFiles", count-1), NULL);

        setup_logs();

        gf_term_connect(term, the_url);
}

void switch_playlist(Bool play_prev)
{
        char szPLE[20];
        u32 idx = 0;
        u32 count;
        const char *ple = gf_cfg_get_key(user.config, "General", "PLEntry");
        if (ple) idx = atoi(ple);

        count = gf_cfg_get_key_count(user.config, "Playlist");
        if (!count) return;
        /*not the first launch*/
        if (strlen(the_url)) {
                if (!idx && play_prev) return;
                if (play_prev) idx--;
                else idx++;
                if (idx>=count) return;
        } else {
                if (idx>=count) idx=0;
        }

        ple = gf_cfg_get_key_name(user.config, "Playlist", idx);
        if (!ple) return;

        sprintf(szPLE, "%d", idx);
        gf_cfg_set_key(user.config, "General", "PLEntry", szPLE);

        strcpy(the_url, ple);
        do_open_file();
}


Bool GPAC_EventProc(void *ptr, GF_Event *evt)
{
        switch (evt->type) {
        case GF_EVENT_DURATION:
                Duration = (u32) (evt->duration.duration*1000);
                CanSeek = evt->duration.can_seek;
                break;
        case GF_EVENT_MESSAGE:
        {
                if (!evt->message.message) return GF_FALSE;
                GF_LOG(GF_LOG_ERROR, GF_LOG_CONSOLE, ("%s: %s\n", evt->message.message, gf_error_to_string(evt->message.error)));
                //set_status((char *) evt->message.message);
        }
        break;
        case GF_EVENT_PROGRESS:
        {
                char *szTitle = "";
                if (evt->progress.progress_type==0) szTitle = "Buffer ";
                else if (evt->progress.progress_type==1) szTitle = "Download ";
                else if (evt->progress.progress_type==2) szTitle = "Import ";
                cbk_on_progress(szTitle, evt->progress.done, evt->progress.total);
        }
        break;

        case GF_EVENT_SIZE:
                break;
        case GF_EVENT_RESOLUTION:
                recompute_res(evt->size.width, evt->size.height);
                do_layout(GF_TRUE);
                break;

        case GF_EVENT_SCENE_SIZE:
                do_layout(GF_TRUE);
                break;
        case GF_EVENT_DBLCLICK:
                set_full_screen();
                return GF_FALSE;
        case GF_EVENT_CONNECT:
                if (evt->connect.is_connected) {
                        is_connected = GF_TRUE;
                        if (!backlight_off) set_backlight_state(GF_TRUE);
                        refresh_recent_files();
                        navigation_on = (gf_term_get_option(term, GF_OPT_NAVIGATION)==GF_NAVIGATE_NONE) ? GF_FALSE : GF_TRUE;
                } else {
                        navigation_on = GF_FALSE;
                        is_connected = GF_FALSE;
                        Duration = 0;
                }
                break;
        case GF_EVENT_EOS:
                if (Duration>2000)
                        gf_term_play_from_time(term, 0, 0);
                break;
        case GF_EVENT_QUIT:
                PostMessage(g_hwnd, WM_DESTROY, 0, 0);
                break;
        case GF_EVENT_KEYDOWN:
                switch (evt->key.key_code) {
                case GF_KEY_ENTER:
                        if (full_screen) set_full_screen();
                        break;
                case GF_KEY_1:
                        ctrl_mod_down = (Bool)!ctrl_mod_down;
                        evt->key.key_code = GF_KEY_CONTROL;
                        evt->type = ctrl_mod_down ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP;
                        gf_term_user_event(term, evt);
                        break;
                case GF_KEY_MEDIAPREVIOUSTRACK:
                        playlist_act = 2;
                        break;
                case GF_KEY_MEDIANEXTTRACK:
                        playlist_act = 1;
                        break;
                }
                break;
        case GF_EVENT_NAVIGATE:
                if (gf_term_is_supported_url(term, evt->navigate.to_url, GF_TRUE, GF_TRUE)) {
                        gf_term_navigate_to(term, evt->navigate.to_url);
                        return GF_TRUE;
                } else {
#ifdef _WIN32_WCE
                        u16 dst[1024];
#endif
                        SHELLEXECUTEINFO info;

                        /*
                                                if (full_screen) gf_term_set_option(term, GF_OPT_FULLSCREEN, 0);
                                                full_screen = 0;
                        */
                        memset(&info, 0, sizeof(SHELLEXECUTEINFO));
                        info.cbSize = sizeof(SHELLEXECUTEINFO);
                        info.lpVerb = _T("open");
                        info.fMask = SEE_MASK_NOCLOSEPROCESS;
                        info.lpFile = _T("iexplore");
#ifdef _WIN32_WCE
                        CE_CharToWide((char *) evt->navigate.to_url, dst);
                        info.lpParameters = (LPCTSTR) dst;
#else
                        info.lpParameters = evt->navigate.to_url;
#endif
                        info.nShow = SW_SHOWNORMAL;
                        ShellExecuteEx(&info);
                }
                return GF_TRUE;
        }
        return GF_FALSE;
}

//#define TERM_NOT_THREADED

Bool LoadTerminal()
{
        /*by default use current dir*/
        strcpy(the_url, ".");

        setup_logs();

        g_hwnd_disp = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE , 0, 0, disp_w, disp_h, g_hwnd, NULL, g_hinst, NULL);

        user.EventProc = GPAC_EventProc;
        /*dummy in this case (global vars) but MUST be non-NULL*/
        user.opaque = user.modules;
        user.os_window_handler = g_hwnd_disp;
#ifdef TERM_NOT_THREADED
        user.init_flags = GF_TERM_NO_DECODER_THREAD | GF_TERM_NO_COMPOSITOR_THREAD | GF_TERM_NO_REGULATION;
#endif

        term = gf_term_new(&user);
        if (!term) {
                gf_modules_del(user.modules);
                gf_cfg_del(user.config);
                memset(&user, 0, sizeof(GF_User));
                return GF_FALSE;
        }

#ifdef _WIN32_WCE
        screen_w = term->compositor->video_out->max_screen_width;
        screen_h = term->compositor->video_out->max_screen_height;
        disp_w = screen_w;
        disp_h = screen_h - menu_h /*- caption_h*/;
#endif

#ifdef TERM_NOT_THREADED
        ::SetTimer(g_hwnd, GPAC_TIMER_ID, GPAC_TIMER_DUR, NULL);
#endif

        const char *str = gf_cfg_get_key(user.config, "General", "StartupFile");
        if (str) {
                do_layout(GF_TRUE);
                strcpy(the_url, str);
                gf_term_connect(term, str);
        }
        return GF_TRUE;
}

void do_layout(Bool notif_size)
{
        u32 w, h;
        if (full_screen) {
                w = screen_w;
                h = screen_h;
                ::ShowWindow(g_hwnd_status, SW_HIDE);
#ifdef _WIN32_WCE
                ::ShowWindow(g_hwnd_menu, SW_HIDE);
#endif

#ifdef _WIN32_WCE
                SHFullScreen(g_hwnd, SHFS_HIDESIPBUTTON);
#endif
                ::MoveWindow(g_hwnd, 0, 0, screen_w, screen_h, 1);
                ::MoveWindow(g_hwnd_disp, 0, 0, screen_w, screen_h, 1);
                SetForegroundWindow(g_hwnd_disp);
        } else {
#ifdef _WIN32_WCE
                ::ShowWindow(g_hwnd_menu, SW_SHOW);
#endif
                if (show_status) {
                        ::MoveWindow(g_hwnd, 0, 0, disp_w, disp_h, 1);
                        ::ShowWindow(g_hwnd_status, SW_SHOW);
                        ::MoveWindow(g_hwnd_status, 0, 0, disp_w, caption_h, 1);
                        ::MoveWindow(g_hwnd_disp, 0, caption_h, disp_w, disp_h - caption_h, 1);
                        w = disp_w;
                        h = disp_h - caption_h*ratio_h;
                } else {
                        ::ShowWindow(g_hwnd_status, SW_HIDE);
//                      ::MoveWindow(g_hwnd, 0, caption_h, disp_w, disp_h, 1);
                        ::MoveWindow(g_hwnd, 0, 0, disp_w, disp_h, 1);
                        ::MoveWindow(g_hwnd_disp, 0, 0, disp_w, disp_h, 1);
                        w = disp_w;
                        h = disp_h;
                }
        }
        if (notif_size && term) gf_term_set_size(term, w, h);
}


void set_backlight_state(Bool disable)
{
#ifdef _WIN32_WCE
        HKEY hKey = 0;
        DWORD dwSize;
        DWORD dwValue;
        HANDLE hBL;
        if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("ControlPanel\\Backlight"), 0, 0, &hKey ) != ERROR_SUCCESS) return;

        if (disable) {
                dwSize = 4;
                RegQueryValueEx(hKey, _T("BatteryTimeout"), NULL, NULL,(unsigned char*) &prev_batt_bl, &dwSize);
                dwSize = 4;
                RegQueryValueEx(hKey, _T("ACTimeout"), NULL, NULL, (unsigned char*) &prev_ac_bl,&dwSize);
                dwSize = 4;
                dwValue = 0xefff ;
                RegSetValueEx(hKey, _T("BatteryTimeout"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize);
                dwSize = 4;
                dwValue = 0xefff ;
                RegSetValueEx( hKey, _T("ACTimeout"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize);
                backlight_off = GF_TRUE;
        } else {
                if (prev_batt_bl) {
                        dwSize = 4;
                        RegSetValueEx(hKey, _T("BatteryTimeout"), NULL, REG_DWORD, (unsigned char *)&prev_batt_bl, dwSize);
                }
                if (prev_ac_bl) {
                        dwSize = 4;
                        RegSetValueEx(hKey, _T("ACTimeout"), NULL, REG_DWORD,(unsigned char *)&prev_ac_bl, dwSize);
                }
                backlight_off = GF_FALSE;
        }
        RegCloseKey(hKey);
        hBL = CreateEvent(NULL, FALSE, FALSE, _T("BackLightChangeEvent"));
        if (hBL) {
                SetEvent(hBL);
                CloseHandle(hBL);
        }
#endif
}

static Bool do_resume = GF_FALSE;
static Bool prev_backlight_state;
void gf_freeze_display(Bool do_gf_freeze)
{
        if (do_gf_freeze) {
                prev_backlight_state = backlight_off;
                do_resume = GF_FALSE;
                if (0 && is_connected && gf_term_get_option(term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) {
                        do_resume= GF_TRUE;
                        gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED);
                }
                /*gf_freeze display*/
                gf_term_set_option(term, GF_OPT_FREEZE_DISPLAY, 1);

                set_backlight_state(GF_FALSE);
                gf_sleep(100);
        } else {
                if (prev_backlight_state) set_backlight_state(GF_TRUE);
                gf_term_set_option(term, GF_OPT_FREEZE_DISPLAY, 0);

                if (do_resume) {
                        gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING);
                        set_backlight_state(GF_TRUE);
                }
        }
}

static void show_taskbar(Bool show_it)
{
#ifdef _WIN32_WCE
        HWND wnd;
        if (!is_ppc) return;

        wnd = GetForegroundWindow();
        wnd = g_hwnd;
        if (show_it) {
                SHFullScreen(wnd, SHFS_SHOWSTARTICON | SHFS_SHOWTASKBAR| SHFS_SHOWSIPBUTTON);
                ::ShowWindow(::FindWindow(_T("HHTaskbar"),NULL), SW_SHOWNA);
        } else {
                ::ShowWindow(::FindWindow(_T("HHTaskbar"),NULL), SW_HIDE);
                SHFullScreen(wnd, SHFS_HIDESTARTICON | SHFS_HIDETASKBAR| SHFS_HIDESIPBUTTON);
        }
#endif
}

void refresh_recent_files()
{
#ifdef _WIN32_WCE
        u32 count = gf_cfg_get_key_count(user.config, "RecentFiles");

        HMENU hMenu = (HMENU)SendMessage(g_hwnd_menu, SHCMBM_GETSUBMENU, 0, ID_MENU_FILE);
        /*pos is hardcoded*/
        hMenu = GetSubMenu(hMenu, 2);

        while (RemoveMenu(hMenu, 0, MF_BYPOSITION)) {}

        for (u32 i=0; i<count; i++) {
                TCHAR txt[100];
                char *name;
                const char *sOpt = gf_cfg_get_key_name(user.config, "RecentFiles", i);
                name = strrchr(sOpt, '\\');
                if (!name) name = strrchr(sOpt, '/');
                if (!name) name = (char *) sOpt;
                else name += 1;

                CE_CharToWide(name, (u16 *) txt);
                AppendMenu(hMenu, MF_STRING, IDM_OPEN_FILE1+i, txt);
        }
#endif
}


void open_file(HWND hwnd)
{
        Bool res;
        char ext_list[4096];
        strcpy(ext_list, "");

        gf_freeze_display(GF_TRUE);

        u32 count = gf_cfg_get_key_count(user.config, "MimeTypes");
        for (u32 i=0; i<count; i++) {
                char szKeyList[1000], *sKey;
                const char *sMime = gf_cfg_get_key_name(user.config, "MimeTypes", i);
                const char *opt = gf_cfg_get_key(user.config, "MimeTypes", sMime);
                strcpy(szKeyList, opt+1);
                sKey = strrchr(szKeyList, '\"');
                if (!sKey) continue;
                sKey[0] = 0;
                strcat(ext_list, szKeyList);
                strcat(ext_list, " ");
        }
#ifdef _WIN32_WCE
        res = gf_file_dialog(g_hinst, hwnd, the_url, ext_list, user.config);
#else
        res = GF_FALSE;
#endif
        gf_freeze_display(GF_FALSE);

        /*let's go*/
        if (res) do_open_file();
}

void load_recent_file(u32 idx)
{
        const char *sOpt = gf_cfg_get_key_name(user.config, "RecentFiles", idx);
        if (sOpt) {
                strcpy(the_url, sOpt);
                do_open_file();
        }
}

BOOL CALLBACK AboutDialogProc(const HWND hWnd, const UINT Msg, const WPARAM wParam, const LPARAM lParam)
{
        BOOL ret = TRUE;
        switch (Msg) {
        case WM_INITDIALOG:
        {
                char szText[4096];
                HWND hctl = GetDlgItem(hWnd, IDC_NAMECTRL);
                sprintf(szText, "GPAC/Osmo4\nversion %s", GPAC_FULL_VERSION);
#ifdef _WIN32_WCE
                TCHAR           psz[80];
                ZeroMemory(psz, sizeof(psz));
                SHINITDLGINFO sid;
                ZeroMemory(&sid, sizeof(sid));
                sid.dwMask  = SHIDIM_FLAGS;
                sid.dwFlags = SHIDIF_SIZEDLGFULLSCREEN;
                sid.hDlg    = hWnd;
                SHInitDialog(&sid);

                SHMENUBARINFO mbi;
                memset(&mbi, 0, sizeof(SHMENUBARINFO));
                mbi.cbSize = sizeof(SHMENUBARINFO);
                mbi.hwndParent = hWnd;
                mbi.nToolBarId = IDR_ABOUT_MENU;
                mbi.hInstRes = g_hinst;
                mbi.nBmpId = 0;
                mbi.cBmpImages = 0;
                SHCreateMenuBar(&mbi);

                u16 swText[4096];
                CE_CharToWide(szText, swText);

                SetWindowText(hctl, (LPCWSTR) swText);
#else
                SetWindowText(hctl, szText);
#endif
                MoveWindow(hctl, 0, 0, screen_w, 40, 1);
                MoveWindow(hWnd, 0, 0, screen_w, disp_w, 1);

        }
        break;
        case WM_COMMAND:
        case WM_CLOSE:
                EndDialog(hWnd, 0);
                break;
        default:
                ret = FALSE;
        }
        return ret;
}
void view_about(HWND hwnd)
{
        gf_freeze_display(GF_TRUE);
//      ::ShowWindow(g_hwnd_mb, SW_HIDE);
        int iResult = DialogBox(g_hinst, MAKEINTRESOURCE(IDD_APPABOUT), hwnd,(DLGPROC)AboutDialogProc);
//      ::ShowWindow(g_hwnd_mb, SW_SHOW);
        gf_freeze_display(GF_FALSE);
}

void pause_file()
{
        if (!is_connected) return;
#ifdef _WIN32_WCE
        TBBUTTONINFO tbbi;
        tbbi.cbSize = sizeof(tbbi);
        tbbi.dwMask = TBIF_TEXT;
#endif

        if (gf_term_get_option(term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) {
                gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED);
#ifdef _WIN32_WCE
                tbbi.pszText = _T("Resume");
#endif
        } else {
                gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING);
#ifdef _WIN32_WCE
                tbbi.pszText = _T("Pause");
#endif
        }
#ifdef _WIN32_WCE
        SendMessage(g_hwnd_menu, TB_SETBUTTONINFO, IDM_FILE_PAUSE, (LPARAM)&tbbi);
#endif
}

void set_svg_progressive()
{
        use_svg_prog = (Bool)!use_svg_prog;
        if (use_svg_prog) {
                gf_cfg_set_key(user.config, "SAXLoader", "Progressive", "yes");
                gf_cfg_set_key(user.config, "SAXLoader", "MaxDuration", "30");
        } else {
                gf_cfg_set_key(user.config, "SAXLoader", "MaxDuration", "0");
                gf_cfg_set_key(user.config, "SAXLoader", "Progressive", "no");
        }
}

void set_gx_mode(u32 mode)
{
        char *opt;
        switch (mode) {
        case 0:
                opt = "raw";
                break;
        case 1:
                opt = "gx";
                break;
        case 2:
                opt = "gdi";
                break;
        }
        gf_cfg_set_key(user.config, "GAPI", "FBAccess", opt);

//      gf_term_del(term);
//      term = gf_term_new(&user);
//      gf_term_disconnect(term);
//      gf_term_connect(term, the_url);
        do_layout(GF_TRUE);
}

void do_copy_paste()
{
        if (!OpenClipboard(g_hwnd)) return;

        /*or we are editing text and clipboard is not empty*/
        if (IsClipboardFormatAvailable(CF_TEXT) && (gf_term_paste_text(term, NULL, GF_TRUE)==GF_OK)) {
                HGLOBAL hglbCopy = GetClipboardData(CF_TEXT);
                if (hglbCopy) {
#ifdef _WIN32_WCE
                        char szString[1024];
                        LPCTSTR paste_string = (LPCTSTR) GlobalLock(hglbCopy);
                        CE_WideToChar((u16 *) paste_string, szString);
                        gf_term_paste_text(term, szString, GF_FALSE);
#else
                        char *szString = (char *)GlobalLock(hglbCopy);
                        gf_term_paste_text(term, szString, GF_FALSE);
#endif
                        GlobalUnlock(hglbCopy);
                }
        }
        /*we have something to copy*/
        else if (gf_term_get_text_selection(term, GF_TRUE)!=NULL) {
                u32 len;
                const char *text = gf_term_get_text_selection(term, GF_FALSE);
                if (text && strlen(text)) {
                        EmptyClipboard();
                        len = strlen(text);

#ifdef _WIN32_WCE
                        HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(u16));
                        LPCTSTR new_string = (LPCTSTR) GlobalLock(hglbCopy);
                        CE_CharToWide((char*)text, (u16*)new_string);
#else
                        HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(u8));
                        char *new_string = (char*) GlobalLock(hglbCopy);
                        strcpy(new_string, text);
#endif
                        GlobalUnlock(hglbCopy);
                        SetClipboardData(CF_TEXT, hglbCopy);
                }
        }
        CloseClipboard();
}

static void rewrite_log_tools(u32 tool)
{
        char *logs;
        if (tool == GF_LOG_ALL) {
                gf_log_set_tool_level(GF_LOG_ALL, log_level);
        } else {
                if (gf_log_tool_level_on(tool, log_level)) {
                        gf_log_set_tool_level(tool, GF_LOG_QUIET);
                } else {
                        gf_log_set_tool_level(tool, log_level);
                }
        }
        logs = gf_log_get_tools_levels();
        if (logs) {
                gf_cfg_set_key(user.config, "General", "Logs", logs);
                gf_free(logs);
        }
        setup_logs();
}

BOOL HandleCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
        switch (LOWORD(wParam)) {
        case IDM_FILE_OPEN:
                open_file(hwnd);
                break;
        case IDM_FILE_LOG_RTI:
                log_rti = (Bool)!log_rti;
                setup_logs();
                break;
        case IDM_FILE_PAUSE:
                pause_file();
                break;
        case IDM_VIEW_ABOUT:
                view_about(hwnd);
                break;
        case IDM_VIEW_FS:
                set_full_screen();
                break;
        case IDM_VIEW_STATUS:
                show_status = (Bool)!show_status;
                gf_cfg_set_key(user.config, "General", "ShowStatusBar", show_status ? "yes" : "no");
                do_layout(GF_TRUE);
                break;
        case IDM_VIEW_CPU:
                view_cpu = (Bool)!view_cpu;
                break;
        case IDM_VIEW_FORCEGL:
                force_2d_gl = (Bool)!force_2d_gl;
                gf_cfg_set_key(user.config, "Compositor", "ForceOpenGL", force_2d_gl ? "yes" : "no");
                gf_term_set_option(term, GF_OPT_USE_OPENGL, force_2d_gl);
                break;
        case IDM_NAV_RESET:
                gf_term_set_option(term, GF_OPT_NAVIGATION_TYPE, 0);
                break;
        case IDM_NAV_NONE:
                gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE);
                break;
        case IDM_NAV_SLIDE:
                gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE);
                break;
        case IDM_NAV_WALK:
                gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_WALK);
                break;
        case IDM_NAV_FLY:
                gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_FLY);
                break;
        case IDM_NAV_EXAMINE:
                gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_EXAMINE);
                break;
        case IDM_NAV_HEADLIGHT:
                gf_term_set_option(term, GF_OPT_HEADLIGHT, !gf_term_get_option(term, GF_OPT_HEADLIGHT) );
                break;
        case IDM_NAV_COL_NONE:
                gf_term_set_option(term, GF_OPT_COLLISION, GF_COLLISION_NONE);
                break;
        case IDM_NAV_COL_REG:
                gf_term_set_option(term, GF_OPT_COLLISION, GF_COLLISION_NORMAL);
                break;
        case IDM_NAV_COL_DISP:
                gf_term_set_option(term, GF_OPT_COLLISION, GF_COLLISION_DISPLACEMENT);
                break;
        case IDM_NAV_GRAVITY:
                gf_term_set_option(term, GF_OPT_GRAVITY, !gf_term_get_option(term, GF_OPT_GRAVITY));
                break;

        case IDM_VIEW_AR_NONE:
                gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP);
                break;
        case IDM_VIEW_AR_FILL:
                gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN);
                break;
        case IDM_VIEW_AR_4_3:
                gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3);
                break;
        case IDM_VIEW_AR_16_9:
                gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9);
                break;

        case IDM_VIEW_LOW_RATE:
                use_low_fps = (Bool)!use_low_fps;
                gf_term_set_simulation_frame_rate(term, use_low_fps ? 15.0 : 30.0);
                break;
        case ID_VIDEO_DIRECTDRAW:
        {
                u32 drend = (gf_term_get_option(term, GF_OPT_DRAW_MODE)==GF_DRAW_MODE_IMMEDIATE) ? GF_DRAW_MODE_DEFER : GF_DRAW_MODE_IMMEDIATE;
                gf_term_set_option(term, GF_OPT_DRAW_MODE, drend);
                gf_cfg_set_key(user.config, "Compositor", "DrawMode", drend ? "immediate" : "defer");
        }
        break;

        case ID_FILE_CUT_PASTE:
                do_copy_paste();
                break;

        case IDM_OPEN_FILE1:
        case IDM_OPEN_FILE2:
        case IDM_OPEN_FILE3:
        case IDM_OPEN_FILE4:
        case IDM_OPEN_FILE5:
        case IDM_OPEN_FILE6:
        case IDM_OPEN_FILE7:
        case IDM_OPEN_FILE8:
        case IDM_OPEN_FILE9:
        case IDM_OPEN_FILE10:
                load_recent_file(LOWORD(wParam) - IDM_OPEN_FILE1);
                break;

        case IDS_CAP_DISABLE_PLAYLIST:
                playlist_navigation_on = (Bool)!playlist_navigation_on;
                break;
        case IDM_VIEW_SVG_LOAD:
                set_svg_progressive();
                break;
        case ID_VIDEO_DIRECTFB:
                set_gx_mode(0);
                break;
        case ID_VIDEO_GAPI:
                set_gx_mode(1);
                break;
        case ID_VIDEO_GDI:
                set_gx_mode(2);
                break;

        case ID_LOGLEVEL_NONE:
                log_level = GF_LOG_QUIET;
                rewrite_log_tools(GF_LOG_ALL);
                break;
        case ID_LOGLEVEL_ERROR:
                log_level = GF_LOG_ERROR;
                rewrite_log_tools(GF_LOG_ALL);
                break;
        case ID_LOGLEVEL_WARNING:
                log_level = GF_LOG_WARNING;
                rewrite_log_tools(GF_LOG_ALL);
                break;
        case ID_LOGLEVEL_INFO:
                log_level = GF_LOG_INFO;
                rewrite_log_tools(GF_LOG_ALL);
                break;
        case ID_LOGLEVEL_DEBUG:
                log_level = GF_LOG_DEBUG;
                rewrite_log_tools(GF_LOG_ALL);
                break;
        case ID_TOOLS_CORE:
                rewrite_log_tools(GF_LOG_CORE);
                break;
        case ID_TOOLS_CODING:
                rewrite_log_tools(GF_LOG_CODING);
                break;
        case ID_TOOLS_CONTAINER:
                rewrite_log_tools(GF_LOG_CONTAINER);
                break;
        case ID_TOOLS_NETWORK:
                rewrite_log_tools(GF_LOG_NETWORK);
                break;
        case ID_TOOLS_RTP:
                rewrite_log_tools(GF_LOG_RTP);
                break;
        case ID_TOOLS_SCRIPT:
                rewrite_log_tools(GF_LOG_SCRIPT);
                break;
        case ID_TOOLS_CODEC:
                rewrite_log_tools(GF_LOG_CODEC);
                break;
        case ID_TOOLS_PARSER:
                rewrite_log_tools(GF_LOG_PARSER);
                break;
        case ID_TOOLS_MEDIA:
                rewrite_log_tools(GF_LOG_MEDIA);
                break;
        case ID_TOOLS_SCENE:
                rewrite_log_tools(GF_LOG_SCENE);
                break;
        case ID_TOOLS_INTERACT:
                rewrite_log_tools(GF_LOG_INTERACT);
                break;
        case ID_TOOLS_COMPOSE:
                rewrite_log_tools(GF_LOG_COMPOSE);
                break;
        case ID_TOOLS_MMIO:
                rewrite_log_tools(GF_LOG_MMIO);
                break;
        case ID_TOOLS_RTI:
                rewrite_log_tools(GF_LOG_RTI);
                break;
        case ID_TOOLS_ALL:
                rewrite_log_tools(GF_LOG_ALL);
                break;
        case ID_TOOLS_NONE:
                log_level = GF_LOG_QUIET;
                rewrite_log_tools(GF_LOG_ALL);
                break;
        case ID_LOGS_RESET:
                if (log_file) {
                        gf_fclose(log_file);
                        log_file = NULL;
                }
                {
                        const char *filename = gf_cfg_get_key(user.config, "General", "LogFile");
                        if (filename) gf_delete_file(filename);
                }
                setup_logs();
                break;

        case IDM_ITEM_QUIT:
                DestroyWindow(hwnd);
                return FALSE;
        }
        return TRUE;
}

static BOOL OnMenuPopup(const HWND hWnd, const WPARAM wParam)
{
        char *opt;
        u32 type;
        CheckMenuItem((HMENU)wParam, IDM_VIEW_STATUS, MF_BYCOMMAND| (show_status ? MF_CHECKED : MF_UNCHECKED) );
        CheckMenuItem((HMENU)wParam, IDM_VIEW_FORCEGL, MF_BYCOMMAND| (force_2d_gl ? MF_CHECKED : MF_UNCHECKED) );
        EnableMenuItem((HMENU)wParam, IDM_VIEW_CPU, MF_BYCOMMAND| (show_status ? MF_ENABLED : MF_GRAYED) );
        if (show_status) CheckMenuItem((HMENU)wParam, IDM_VIEW_CPU, MF_BYCOMMAND| (view_cpu ? MF_CHECKED : MF_UNCHECKED) );
        CheckMenuItem((HMENU)wParam, IDM_VIEW_LOW_RATE, MF_BYCOMMAND| (use_low_fps ? MF_CHECKED : MF_UNCHECKED) );

        EnableMenuItem((HMENU)wParam, ID_VIDEO_DIRECTDRAW, MF_BYCOMMAND| (!force_2d_gl ? MF_ENABLED : MF_GRAYED) );
        CheckMenuItem((HMENU)wParam, ID_VIDEO_DIRECTDRAW, MF_BYCOMMAND| (!force_2d_gl && gf_term_get_option(term, GF_OPT_DRAW_MODE) ? MF_CHECKED : MF_UNCHECKED) );

        CheckMenuItem((HMENU)wParam, IDM_VIEW_SVG_LOAD, MF_BYCOMMAND| (use_svg_prog ? MF_CHECKED : MF_UNCHECKED) );

        opt = (char *)gf_cfg_get_key(user.config, "GAPI", "FBAccess");
        if (!opt) opt = "raw";
        CheckMenuItem((HMENU)wParam, ID_VIDEO_DIRECTFB, MF_BYCOMMAND| ( (!strcmp(opt,"raw")) ? MF_CHECKED : MF_UNCHECKED) );
        CheckMenuItem((HMENU)wParam, ID_VIDEO_GAPI, MF_BYCOMMAND| ( (!strcmp(opt,"gx")) ? MF_CHECKED : MF_UNCHECKED) );
        CheckMenuItem((HMENU)wParam, ID_VIDEO_GDI, MF_BYCOMMAND| ( (!strcmp(opt,"gdi")) ? MF_CHECKED : MF_UNCHECKED) );


        type = gf_term_get_option(term, GF_OPT_ASPECT_RATIO);
        CheckMenuItem((HMENU)wParam, IDS_CAP_DISABLE_PLAYLIST, MF_BYCOMMAND| (!playlist_navigation_on ? MF_CHECKED : MF_UNCHECKED) );
        CheckMenuItem((HMENU)wParam, IDM_VIEW_AR_NONE, MF_BYCOMMAND| (type==GF_ASPECT_RATIO_KEEP) ? MF_CHECKED : MF_UNCHECKED);
        CheckMenuItem((HMENU)wParam, IDM_VIEW_AR_FILL, MF_BYCOMMAND| (type==GF_ASPECT_RATIO_FILL_SCREEN) ? MF_CHECKED : MF_UNCHECKED);
        CheckMenuItem((HMENU)wParam, IDM_VIEW_AR_4_3, MF_BYCOMMAND| (type==GF_ASPECT_RATIO_4_3) ? MF_CHECKED : MF_UNCHECKED);
        CheckMenuItem((HMENU)wParam, IDM_VIEW_AR_16_9, MF_BYCOMMAND| (type==GF_ASPECT_RATIO_16_9) ? MF_CHECKED : MF_UNCHECKED);

        EnableMenuItem((HMENU)wParam, IDM_FILE_PAUSE, MF_BYCOMMAND| (is_connected ? MF_ENABLED : MF_GRAYED) );

        if (/*we have something to copy*/
            (gf_term_get_text_selection(term, GF_TRUE)!=NULL)
            /*or we are editing text and clipboard is not empty*/
            || (IsClipboardFormatAvailable(CF_TEXT) && (gf_term_paste_text(term, NULL, GF_TRUE)==GF_OK))
        ) {
                EnableMenuItem((HMENU)wParam, ID_FILE_CUT_PASTE, MF_BYCOMMAND| MF_ENABLED);
        } else {
                EnableMenuItem((HMENU)wParam, ID_FILE_CUT_PASTE, MF_BYCOMMAND| MF_GRAYED);
        }

        CheckMenuItem((HMENU)wParam, IDM_FILE_LOG_RTI, MF_BYCOMMAND| (log_rti) ? MF_CHECKED : MF_UNCHECKED);

        if (!is_connected) type = 0;
        else type = gf_term_get_option(term, GF_OPT_NAVIGATION_TYPE);
        navigation_on = type ? GF_TRUE : GF_FALSE;

        EnableMenuItem((HMENU)wParam, IDM_NAV_NONE, MF_BYCOMMAND | (!type ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_SLIDE, MF_BYCOMMAND | (!type ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_RESET, MF_BYCOMMAND | (!type ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_WALK, MF_BYCOMMAND | ( (type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_FLY, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_EXAMINE, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_COL_NONE, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_COL_REG, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_COL_DISP, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_GRAVITY, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) );
        EnableMenuItem((HMENU)wParam, IDM_NAV_HEADLIGHT, MF_BYCOMMAND | ( (type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) );

        if (type) {
                u32 mode = gf_term_get_option(term, GF_OPT_NAVIGATION);
                navigation_on = (mode==GF_NAVIGATE_NONE) ? GF_FALSE : GF_TRUE;
                CheckMenuItem((HMENU)wParam, IDM_NAV_NONE, MF_BYCOMMAND | ( (mode==GF_NAVIGATE_NONE) ? MF_CHECKED : MF_UNCHECKED) );
                CheckMenuItem((HMENU)wParam, IDM_NAV_SLIDE, MF_BYCOMMAND | ( (mode==GF_NAVIGATE_SLIDE) ? MF_CHECKED : MF_UNCHECKED) );
                CheckMenuItem((HMENU)wParam, IDM_NAV_WALK, MF_BYCOMMAND | ( (mode==GF_NAVIGATE_WALK) ? MF_CHECKED : MF_UNCHECKED) );
                CheckMenuItem((HMENU)wParam, IDM_NAV_FLY, MF_BYCOMMAND | ((mode==GF_NAVIGATE_FLY) ? MF_CHECKED : MF_UNCHECKED) );
                CheckMenuItem((HMENU)wParam, IDM_NAV_EXAMINE, MF_BYCOMMAND | ((mode==GF_NAVIGATE_EXAMINE) ? MF_CHECKED : MF_UNCHECKED) );

                if (type==GF_NAVIGATE_TYPE_3D) {
                        CheckMenuItem((HMENU)wParam, IDM_NAV_HEADLIGHT, MF_BYCOMMAND | ( gf_term_get_option(term, GF_OPT_HEADLIGHT) ? MF_CHECKED : MF_UNCHECKED) );
                        CheckMenuItem((HMENU)wParam, IDM_NAV_GRAVITY, MF_BYCOMMAND | ( gf_term_get_option(term, GF_OPT_GRAVITY) ? MF_CHECKED : MF_UNCHECKED) );
                        type = gf_term_get_option(term, GF_OPT_COLLISION);
                        CheckMenuItem((HMENU)wParam, IDM_NAV_COL_NONE, MF_BYCOMMAND | ( (type==GF_COLLISION_NONE) ? MF_CHECKED : MF_UNCHECKED) );
                        CheckMenuItem((HMENU)wParam, IDM_NAV_COL_REG, MF_BYCOMMAND | ( (type==GF_COLLISION_NORMAL) ? MF_CHECKED : MF_UNCHECKED) );
                        CheckMenuItem((HMENU)wParam, IDM_NAV_COL_DISP, MF_BYCOMMAND | ( (type==GF_COLLISION_DISPLACEMENT) ? MF_CHECKED : MF_UNCHECKED) );
                }
        }

        opt = (char *) gf_cfg_get_key(user.config, "General", "Logs");
        CheckMenuItem((HMENU)wParam, ID_LOGLEVEL_NONE, MF_BYCOMMAND | ( strstr(opt, "quiet") ? MF_CHECKED : MF_UNCHECKED) );
        CheckMenuItem((HMENU)wParam, ID_LOGLEVEL_ERROR, MF_BYCOMMAND | ( strstr(opt, "error") ? MF_CHECKED : MF_UNCHECKED) );
        CheckMenuItem((HMENU)wParam, ID_LOGLEVEL_WARNING, MF_BYCOMMAND | ( strstr(opt, "warning") ? MF_CHECKED : MF_UNCHECKED) );
        CheckMenuItem((HMENU)wParam, ID_LOGLEVEL_INFO, MF_BYCOMMAND | ( strstr(opt, "info") ? MF_CHECKED : MF_UNCHECKED) );
        CheckMenuItem((HMENU)wParam, ID_LOGLEVEL_DEBUG, MF_BYCOMMAND | ( strstr(opt, "debug") ? MF_CHECKED : MF_UNCHECKED) );

#define CHECK_TOOL(_ID, _name) CheckMenuItem((HMENU)wParam, _ID, MF_BYCOMMAND | ( ((strstr(opt, _name) != NULL) || !strcmp(opt, "all")) ? MF_CHECKED : MF_UNCHECKED) );
        opt = (char *) gf_cfg_get_key(user.config, "General", "Logs");
        CHECK_TOOL(ID_TOOLS_CORE, "core");
        CHECK_TOOL(ID_TOOLS_CODING, "coding");
        CHECK_TOOL(ID_TOOLS_CONTAINER, "container");
        CHECK_TOOL(ID_TOOLS_NETWORK, "network");
        CHECK_TOOL(ID_TOOLS_RTP, "rtp");
        CHECK_TOOL(ID_TOOLS_SYNC, "sync");
        CHECK_TOOL(ID_TOOLS_SCRIPT, "script");
        CHECK_TOOL(ID_TOOLS_CODEC, "codec");
        CHECK_TOOL(ID_TOOLS_PARSER, "parser");
        CHECK_TOOL(ID_TOOLS_MEDIA, "media");
        CHECK_TOOL(ID_TOOLS_SCENE, "scene");
        CHECK_TOOL(ID_TOOLS_INTERACT, "interact");
        CHECK_TOOL(ID_TOOLS_COMPOSE, "compose");
        CHECK_TOOL(ID_TOOLS_MMIO, "mmio");
        CHECK_TOOL(ID_TOOLS_RTI, "rti");


        return TRUE;
}


BOOL CALLBACK MainWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
        switch (msg) {
        case WM_CREATE:
        {
#ifdef _WIN32_WCE
                SHMENUBARINFO mbi;
                memset(&mbi, 0, sizeof(SHMENUBARINFO));
                mbi.cbSize = sizeof(SHMENUBARINFO);
                mbi.hwndParent = hwnd;
                mbi.hInstRes = g_hinst;
                mbi.nBmpId = 0;
                mbi.cBmpImages = 0;

                mbi.nToolBarId = IDM_MAIN_MENU;
                SHCreateMenuBar(&mbi);
                g_hwnd_menu = mbi.hwndMB;
#else
                g_hwnd_menu = NULL;
#endif

                g_hwnd_status = CreateWindow(TEXT("STATIC"), TEXT("Status"), WS_CHILD|WS_VISIBLE|SS_LEFT, 0, 0, disp_w, caption_h, hwnd, NULL, g_hinst, NULL);

                do_layout(GF_TRUE);
        }
        break;

        case WM_COMMAND:
                if (HandleCommand(hwnd, wParam, lParam))
                        return DefWindowProc(hwnd, msg, wParam, lParam);
                break;
        case WM_TIMER:
                if (wParam==STATE_TIMER_ID) update_state_info();
#ifdef TERM_NOT_THREADED
                else gf_term_process_step(term);
#endif
                break;
        case WM_HOTKEY:
                break;
        case WM_KEYDOWN:
                if (playlist_navigation_on && !navigation_on) {
                        if (wParam==VK_LEFT) {
                                switch_playlist(GF_TRUE);
                                break;
                        }
                        else if (wParam==VK_RIGHT) {
                                switch_playlist(GF_FALSE);
                                break;
                        }
                }
        /*fall through*/
        case WM_SYSKEYDOWN:
        case WM_SYSKEYUP:
        case WM_KEYUP:
        case WM_CHAR:
        case WM_MOUSEMOVE:
        case WM_LBUTTONDOWN:
        case WM_LBUTTONDBLCLK:
        case WM_LBUTTONUP:
                ::SendMessage(g_hwnd_disp, msg, wParam, lParam);
                return 0;
        case WM_INITMENUPOPUP:
                OnMenuPopup(hwnd, wParam);
                break;
        case WM_CLOSE:
                DestroyWindow(hwnd);
                break;
        case WM_SETFOCUS:
                gf_freeze_display(GF_FALSE);
                break;
        case WM_KILLFOCUS:
                if ((HWND) wParam==g_hwnd) {
                        gf_freeze_display(GF_TRUE);
                }
                break;
        case WM_ACTIVATE:
                if (WA_INACTIVE != LOWORD(wParam)) {
                        if ((HWND) lParam == g_hwnd) {
                                gf_freeze_display(GF_FALSE);
                                SetFocus(hwnd);
                        }
                } else {
                        if ((HWND) lParam == g_hwnd_disp) {
                                gf_freeze_display(GF_TRUE);
                        }
                }
                break;
        case WM_LOADTERM:
                if (!LoadTerminal()) {
                        MessageBox(hwnd, _T("Cannot load GPAC"), _T("Error"), MB_OK);
                        PostQuitMessage(0);
                }
                break;
        case WM_DESTROY:
                PostQuitMessage(0);
                break;
        default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }

        return 0;
}

BOOL InitInstance (int CmdShow)
{
        WNDCLASS wc;

        wc.style                        = 0;
        wc.lpfnWndProc          = (WNDPROC) MainWndProc;
        wc.cbClsExtra           = 0;
        wc.cbWndExtra           = 0;
        wc.hInstance            = g_hinst;
        wc.hIcon                        = LoadIcon(g_hinst, MAKEINTRESOURCE(IDI_ICON));
        wc.hCursor                      = 0;
        wc.hbrBackground        = (HBRUSH) GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName         = 0;
        wc.lpszClassName        = _T("Osmophone");
        RegisterClass(&wc);

#ifdef _WIN32_WCE
        int style = WS_VISIBLE;
#else
        int style = WS_POPUP;
#endif

        g_hwnd = CreateWindow(_T("Osmophone"), _T("Osmophone"),
                              style,
                              0, caption_h, disp_w, disp_h,
                              NULL, NULL, g_hinst, NULL);

        if (!g_hwnd) return FALSE;

        ShowWindow(g_hwnd, CmdShow);

        refresh_recent_files();

        ::SetTimer(g_hwnd, STATE_TIMER_ID, STATE_TIMER_DUR, NULL);
        do_layout(GF_TRUE);

        set_status("Loading Terminal");
        PostMessage(g_hwnd, WM_LOADTERM, 0, 0);
        set_status("Ready");
        return TRUE;
}

#ifndef GETRAWFRAMEBUFFER
#define GETRAWFRAMEBUFFER   0x00020001
typedef struct _RawFrameBufferInfo
{
        WORD wFormat;
        WORD wBPP;
        VOID *pFramePointer;
        int     cxStride;
        int     cyStride;
        int cxPixels;
        int cyPixels;
} RawFrameBufferInfo;

#define FORMAT_565 1
#define FORMAT_555 2
#define FORMAT_OTHER 3
#endif

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
#ifdef _WIN32_WCE
                   LPWSTR lpCmdLine,
#else
                   LPSTR lpCmdLine,
#endif
                   int nShowCmd
                  ) {
        MSG     msg;

        HWND    hwndOld = NULL;
        const char *str;
        Bool initial_launch = GF_FALSE;

        if (hwndOld = FindWindow(_T("Osmophone"), NULL))
        {
                SetForegroundWindow(hwndOld);
                return 0;
        }

        memset(&user, 0, sizeof(GF_User));
        term = NULL;

        g_hinst = hInstance;

        screen_w = GetSystemMetrics(SM_CXSCREEN);
        screen_h = GetSystemMetrics(SM_CYSCREEN);

        /*are we in low res or high res*/
        RawFrameBufferInfo Info;
        HDC DC = GetDC(NULL);
        ExtEscape(DC, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char*)&Info);
        ReleaseDC(NULL,DC);
        if (Info.pFramePointer) {
                recompute_res(Info.cxPixels, Info.cyPixels);
        } else {
                recompute_res(screen_w, screen_h);
        }



#ifdef _WIN32_WCE
        TCHAR      szBuf[MAX_PATH];
        SystemParametersInfo(SPI_GETPLATFORMTYPE, MAX_PATH, szBuf, 0);
        if (! lstrcmp(szBuf, __TEXT("PocketPC"))) is_ppc = GF_TRUE;
        else if (! lstrcmp(szBuf, __TEXT("Palm PC2"))) is_ppc = GF_TRUE;
#endif


        user.config = gf_cfg_init(NULL, &initial_launch);
        if (!user.config) {
                MessageBox(NULL, _T("Couldn't locate GPAC config file"), _T("Fatal Error"), MB_OK);
                return 0;
        }

        str = gf_cfg_get_key(user.config, "Compositor", "ScreenWidth");
        if (str) screen_w = atoi(str);
        str = gf_cfg_get_key(user.config, "Compositor", "ScreenHeight");
        if (str) screen_h = atoi(str);
        disp_w = screen_w;
#ifdef _WIN32_WCE
        disp_h = screen_h - menu_h /*- caption_h*/;
#else
        disp_h = screen_h;
#endif

        gf_sys_init(GF_MemTrackerNone);
        user.modules = gf_modules_new(NULL, user.config);
        if (!gf_modules_get_count(user.modules)) {
                MessageBox(GetForegroundWindow(), _T("No modules found"), _T("GPAC Init Error"), MB_OK);
                gf_modules_del(user.modules);
                gf_cfg_del(user.config);
                memset(&user, 0, sizeof(GF_User));
                gf_sys_close();
                return 0;
        }

        /*first launch, register all files ext*/
        if (initial_launch) {
                /*FFMPEG registration - FFMPEG DLLs compiled with CEGCC cannot be loaded directly under WM 6.1
                cf http://cegcc.sourceforge.net/docs/faq.html#DllDoesNotWorkWithWindowsMobile6.1
                */
                HKEY hKey = NULL;
                DWORD dwSize;
                DWORD dwValue;
                RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("System\\Loader\\LoadModuleLow"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwSize);
                dwSize = 4;
                dwValue = 1;
                LONG res = RegSetValueEx(hKey, _T("avcodec-52.dll"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize);
                res = RegSetValueEx(hKey, _T("avformat-52.dll"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize);
                res = RegSetValueEx(hKey, _T("avutil-50.dll"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize);
                res = RegSetValueEx(hKey, _T("swscale-0.dll"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize);
                RegCloseKey(hKey);

                u32 i;
                for (i=0; i<gf_modules_get_count(user.modules); i++) {
                        GF_InputService *ifce = (GF_InputService *) gf_modules_load_interface(user.modules, i, GF_NET_CLIENT_INTERFACE);
                        if (!ifce) continue;
                        if (ifce) {
                                ifce->CanHandleURL(ifce, "test.test");
                                gf_modules_close_interface((GF_BaseInterface *)ifce);
                        }
                }
                MessageBox(NULL, _T("Thank you for installing GPAC"), _T("Initial setup done"), MB_OK);
        }

        str = gf_cfg_get_key(user.config, "General", "Loop");
        loop = (!str || !stricmp(str, "yes")) ? GF_TRUE : GF_FALSE;

        str = gf_cfg_get_key(user.config, "SAXLoader", "Progressive");
        use_svg_prog = (str && !strcmp(str, "yes")) ? GF_TRUE : GF_FALSE;

        str = gf_cfg_get_key(user.config, "General", "RTIRefreshPeriod");
        if (str) {
                rti_update_time_ms = atoi(str);
        } else {
                gf_cfg_set_key(user.config, "General", "RTIRefreshPeriod", "200");
        }

        str = gf_cfg_get_key(user.config, "General", "ShowStatusBar");
        show_status = (str && !strcmp(str, "yes")) ? GF_TRUE : GF_FALSE;


#ifdef _WIN32_WCE
        if (is_ppc) GXOpenInput();
#endif

        if (InitInstance(nShowCmd)) {
                SetForegroundWindow(g_hwnd);
                show_taskbar(GF_FALSE);

                force_2d_gl = (Bool)gf_term_get_option(term, GF_OPT_USE_OPENGL);

                while (GetMessage(&msg, NULL, 0,0) == TRUE) {
                        TranslateMessage (&msg);
                        DispatchMessage (&msg);

                        if (playlist_act) {
                                switch_playlist((Bool)(playlist_act-1));
                                playlist_act = 0;
                        }
                }
                show_taskbar(GF_TRUE);
        }
#ifdef _WIN32_WCE
        if (is_ppc) GXCloseInput();
#endif

        /*and destroy*/
        if (term) gf_term_del(term);
        if (user.modules) gf_modules_del(user.modules);
        if (user.config) gf_cfg_del(user.config);

        if (backlight_off) set_backlight_state(GF_FALSE);

        gf_sys_close();
        if (log_file) gf_fclose(log_file);
        return 0;
}

/* [<][>][^][v][top][bottom][index][help] */