Benoît Minisini 2eb5d8b8ca [GB.GTK]
* NEW: Rect is a new class that represents a Rectangle. It has some useful
  methods like Contains, Union or Intersection.

[GB.QT4]
* NEW: Rect is a new class that represents a Rectangle. It has some useful
  methods like Contains, Union or Intersection.


git-svn-id: svn://localhost/gambas/trunk@3427 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2011-01-02 00:39:08 +00:00

514 lines
11 KiB
C++

/***************************************************************************
main.cpp
(c) 2004-2006 - Daniel Campos Fernández <dcamposf@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
#define __MAIN_C
#include <stdio.h>
#include "gmemory.h"
#include "main.h"
#include "gb.image.h"
#include "gb.gtk.h"
#include "watcher.h"
#include "x11.h"
#include "crect.h"
#include "CScreen.h"
#include "CDraw.h"
#include "CConst.h"
#include "CColor.h"
#include "CFont.h"
#include "CKey.h"
#include "CPicture.h"
#include "CImage.h"
#include "CClipboard.h"
#include "CMouse.h"
#include "CMessage.h"
#include "CDialog.h"
#include "CWatcher.h"
#include "CWidget.h"
#include "CProgress.h"
#include "CDrawingArea.h"
#include "CContainer.h"
#include "CFrame.h"
#include "CMenu.h"
#include "CWindow.h"
#include "CLabel.h"
#include "CButton.h"
#include "CPictureBox.h"
#include "CTextBox.h"
#include "CTextArea.h"
#include "CListBox.h"
#include "CTreeView.h"
#include "CSlider.h"
#include "CTabStrip.h"
#include "CTrayIcon.h"
#include "CScrollView.h"
#include "CSpinBox.h"
#include "CSplitter.h"
#include "CStock.h"
#include "CIconView.h"
#include "CGridView.h"
#include "CSeparator.h"
#include "cprinter.h"
#include "csvgimage.h"
#include <gtk/gtk.h>
#include <string.h>
GB_CLASS CLASS_Picture;
GB_CLASS CLASS_Image;
GB_CLASS CLASS_DrawingArea;
GB_CLASS CLASS_Menu;
GB_CLASS CLASS_Window;
GB_CLASS CLASS_Printer;
GB_CLASS CLASS_SvgImage;
static void my_lang(char *lang,int rtl1);
static void my_error(int code,char *error,char *where);
static void my_quit (void);
static void my_main(int *argc, char **argv);
static void my_timer(GB_TIMER *timer,bool on);
static void my_wait(int duration);
static void my_post(void);
static int my_loop();
static void my_watch(int fd, int type, void *callback, intptr_t param);
static bool post_Check=false;
static bool _application_keypress = false;
static GB_FUNCTION _application_keypress_func;
int MAIN_scale = 0;
extern "C"
{
GB_INTERFACE GB EXPORT;
IMAGE_INTERFACE IMAGE EXPORT;
GB_DESC *GB_CLASSES[] EXPORT =
{
RectDesc,
ScreenDesc,
ScreensDesc,
DesktopDesc,
ApplicationTooltipDesc,
ApplicationDesc,
CSelectDesc,
CAlignDesc,
CArrangeDesc,
CBorderDesc,
CScrollDesc,
CLineDesc,
CFillDesc,
CColorDesc,
CFontsDesc,
CFontDesc,
CKeyDesc,
CImageDesc,
CPictureDesc,
CClipboardDesc,
CDragDesc,
CCursorDesc,
CMouseDesc,
CMessageDesc,
CDialogDesc,
CWatcherDesc,
CWidgetDesc,
CChildrenDesc,
CContainerDesc,
CDrawingAreaDesc,
CFrameDesc,
CHSplitDesc,
CVSplitDesc,
CUserControlDesc,
CUserContainerDesc,
CPanelDesc,
CHBoxDesc,
CVBoxDesc,
CHPanelDesc,
CVPanelDesc,
CMenuDesc,
CMenuChildrenDesc,
CTrayIconDesc,
CTrayIconsDesc,
CWindowMenusDesc,
CWindowControlsDesc,
CWindowTypeDesc,
CWindowDesc,
CWindowsDesc,
CFormDesc,
CProgressDesc,
CLabelDesc,
CTextLabelDesc,
CSliderDesc,
CScrollBarDesc,
CButtonDesc,
CToggleButtonDesc,
CCheckBoxDesc,
CRadioButtonDesc,
CToolButtonDesc,
CPictureBoxDesc,
CMovieBoxDesc,
CListBoxDesc,
CListBoxItemDesc,
CTextBoxSelectionDesc,
CTextBoxDesc,
CTextAreaDesc,
CTextAreaSelectionDesc,
CComboBoxDesc,
CComboBoxItemDesc,
CListViewItemDesc,
CListViewDesc,
CTreeViewItemDesc,
CTreeViewDesc,
CIconViewItemDesc,
CIconViewDesc,
CColumnViewItemDesc,
CColumnViewColumnDesc,
CColumnViewColumnsDesc,
CColumnViewDesc,
CTabStripDesc,
CTabDesc,
CTabChildrenDesc,
CPluginDesc,
CScrollViewDesc,
CSpinBoxDesc,
CSeparatorDesc,
CGridViewItemDesc,
CGridViewDataDesc,
CGridViewColumnDesc,
CGridViewRowDesc,
CGridViewColumnsDesc,
CGridViewRowsDesc,
CGridViewDesc,
CStockDesc,
PrinterDesc,
SvgImageDesc,
NULL
};
void *GB_GTK_1[] EXPORT =
{
(void *)GTK_INTERFACE_VERSION,
(void *)my_main,
(void *)GTK_GetPicture,
(void *)GTK_GetImage,
(void *)CGRIDVIEW_footer,
(void *)CGRIDVIEW_column_footer_text,
(void *)CGRIDVIEW_columns_get,
(void *)DRAW_get_drawable,
(void *)DRAW_get_style,
(void *)DRAW_get_state,
(void *)DRAW_get_shadow,
(void *)DRAW_set_state,
(void *)DRAW_set_shadow,
NULL
};
const char *GB_INCLUDE EXPORT = "gb.draw";
int EXPORT GB_INIT(void)
{
GB.Hook(GB_HOOK_QUIT, (void *)my_quit);
GB.Hook(GB_HOOK_MAIN, (void *)my_main);
GB.Hook(GB_HOOK_WAIT, (void *)my_wait);
GB.Hook(GB_HOOK_LOOP, (void *)my_loop);
GB.Hook(GB_HOOK_TIMER,(void *)my_timer);
GB.Hook(GB_HOOK_WATCH,(void *)my_watch);
GB.Hook(GB_HOOK_POST,(void*)my_post);
GB.Hook(GB_HOOK_ERROR,(void*)my_error);
GB.Hook(GB_HOOK_LANG,(void*)my_lang);
// Thanks again to GTK+ 2.18 :-(
#if GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 18
//putenv((char *)"GDK_NATIVE_WINDOWS=1");
#endif
GB.LoadComponent("gb.draw");
GB.GetInterface("gb.image", IMAGE_INTERFACE_VERSION, &IMAGE);
IMAGE.SetDefaultFormat(GB_IMAGE_RGBA);
DRAW_init();
CWatcher::init();
//CLASS_Control = GB.FindClass("Control");
//CLASS_Container = GB.FindClass("Container");
//CLASS_UserControl = GB.FindClass("UserControl");
//CLASS_UserContainer = GB.FindClass("UserContainer");
CLASS_Window = GB.FindClass("Window");
CLASS_Menu = GB.FindClass("Menu");
CLASS_Picture = GB.FindClass("Picture");
//CLASS_Drawing = GB.FindClass("Drawing");
CLASS_DrawingArea = GB.FindClass("DrawingArea");
CLASS_Printer = GB.FindClass("Printer");
CLASS_Image = GB.FindClass("Image");
CLASS_SvgImage = GB.FindClass("SvgImage");
return -1;
}
void EXPORT GB_EXIT()
{
CWatcher::exit();
}
int EXPORT GB_INFO(const char *key, void **value)
{
if (!strcasecmp(key, "DISPLAY"))
{
#ifdef GDK_WINDOWING_X11
#ifndef GAMBAS_DIRECTFB
*value = (void *)gdk_x11_display_get_xdisplay(gdk_display_get_default());
#else
// For DirectFB
*value=0;
stub("DIRECTFB/EXPORT GB_INFO");
#endif
#else
// For Win32
*value=0;
stub("no-X11/EXPORT GB_INFO");
#endif
return TRUE;
}
else if (!strcasecmp(key, "ROOT_WINDOW"))
{
#ifdef GDK_WINDOWING_X11
#ifndef GAMBAS_DIRECTFB
*value = (void *)gdk_x11_get_default_root_xwindow();
#else
// For DirectFB
*value=0;
stub("DIRECTFB/EXPORT GB_INFO");
#endif
#else
// For Win32
*value=0;
stub("no-X11/EXPORT GB_INFO");
#endif
return TRUE;
}
else
return FALSE;
}
}
void my_quit (void)
{
CWINDOW *win=WINDOW_get_main();
gApplication::suspendEvents(false);
if (win)
{
while (gtk_events_pending ()) gtk_main_iteration();
if (win->ob.widget) ((gMainWindow*)win->ob.widget)->destroy();
while (gtk_events_pending ()) gtk_main_iteration();
}
}
static bool global_key_event_handler(int type)
{
GB.Call(&_application_keypress_func, 0, FALSE);
return GB.Stopped();
}
static void my_main(int *argc, char **argv)
{
static bool init = false;
if (init)
return;
gApplication::init(argc, &argv);
gApplication::setDefaultTitle(GB.Application.Title());
gDesktop::init();
MAIN_scale = gDesktop::scale();
#ifdef GDK_WINDOWING_X11
X11_init(gdk_x11_display_get_xdisplay(gdk_display_get_default()), gdk_x11_get_default_root_xwindow());
#endif
if (GB.GetFunction(&_application_keypress_func, (void *)GB.Application.StartupClass(), "Application_KeyPress", "", "") == 0)
{
_application_keypress = true;
gApplication::onKeyEvent = global_key_event_handler;
}
init = true;
}
/*static void raise_timer(GB_TIMER *timer)
{
GB.RaiseTimer(timer);
GB.Unref(POINTER(&timer));
}*/
typedef
struct {
GTimer *timer;
int timeout;
}
MyTimerTag;
gboolean my_timer_function(GB_TIMER *timer)
{
if (timer->id)
{
GB.RaiseTimer(timer);
if (timer->id)
{
MyTimerTag *tag = (MyTimerTag *)timer->tag;
GTimer *t = tag->timer;
int elapsed = (int)(g_timer_elapsed(t, NULL) * 1000) - tag->timeout;
int next = timer->delay - elapsed;
if (next < 10)
next = 10;
tag->timeout = next;
g_timer_start(t);
timer->id = (intptr_t)g_timeout_add(next, (GSourceFunc)my_timer_function,(gpointer)timer);
//fprintf(stderr, "elapsed = %d delay = %d next = %d\n", elapsed, timer->delay, next);
}
}
return false;
}
static void my_timer(GB_TIMER *timer,bool on)
{
if (timer->id) {
MyTimerTag *tag = (MyTimerTag *)timer->tag;
g_source_remove(timer->id);
g_timer_destroy(tag->timer);
g_free(tag);
timer->id = 0;
timer->tag = 0;
}
if (on)
{
MyTimerTag *tag = g_new(MyTimerTag, 1);
tag->timer = g_timer_new();
tag->timeout = timer->delay;
timer->tag = (intptr_t)tag;
timer->id = (intptr_t)g_timeout_add(timer->delay,(GSourceFunc)my_timer_function,(gpointer)timer);
return;
}
}
static void my_post(void)
{
post_Check=true;
}
static bool must_quit(void)
{
//fprintf(stderr, "must_quit: %p %d\n", WINDOW_get_main(), CWatcher::count());
return !WINDOW_get_main() && CWatcher::count() == 0; // && in_event_loop;
}
static int my_loop()
{
gControl::cleanRemovedControls();
while (!must_quit())
do_iteration(false);
while (gtk_events_pending ())
gtk_main_iteration();
CWatcher::Clear();
gApplication::exit();
return 0;
}
static void my_wait(int duration)
{
do_iteration(true, true);
}
static void my_watch(int fd, int type, void *callback, intptr_t param)
{
CWatcher::Add(fd,type,callback,param);
}
static void my_error(int code,char *error,char *where)
{
char *showstr;
char scode[10];
sprintf(scode,"%d",code);
showstr=g_strconcat("<b>This application has raised an unexpected<br>error and must abort.</b><p>[", scode, "] ", error, ".\n", where, (void *)NULL);
gMessage::setTitle(GB.Application.Title());
gMessage::showError(showstr,NULL,NULL,NULL);
g_free(showstr);
}
static void my_lang(char *lang,int rtl)
{
int bucle, ct;
gControl *iter;
if (rtl==1)
gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL);
else
gtk_widget_set_default_direction(GTK_TEXT_DIR_LTR);
ct=gApplication::controlCount();
for (bucle=0;bucle<ct;bucle++)
{
iter=gApplication::controlItem(bucle);
if (iter->isVisible() && iter->isContainer())
((gContainer*)iter)->performArrange();
}
}
void do_iteration(bool do_not_block, bool do_not_sleep)
{
struct timespec mywait;
gApplication::_loopLevel++;
if (do_not_block)
{
if (gtk_events_pending ())
gtk_main_iteration_do (false);
else if (!do_not_sleep)
{
mywait.tv_sec=0;
mywait.tv_nsec=100000;
nanosleep(&mywait,NULL);
}
}
else
gtk_main_iteration_do(true);
gApplication::_loopLevel--;
if (post_Check) { post_Check=false; GB.CheckPost(); }
gControl::cleanRemovedControls();
}