1998-10-20 17:25:25 +04:00
|
|
|
//
|
2011-07-19 08:49:30 +04:00
|
|
|
//
|
2023-11-04 13:30:45 +03:00
|
|
|
// Copyright 1998-2023 by Bill Spitzak and others.
|
2011-07-19 08:49:30 +04:00
|
|
|
//
|
|
|
|
// This library is free software. Distribution and use rights are outlined in
|
|
|
|
// the file "COPYING" which should have been included with this file. If this
|
|
|
|
// file is missing or damaged, see the license at:
|
|
|
|
//
|
2020-07-01 19:03:10 +03:00
|
|
|
// https://www.fltk.org/COPYING.php
|
2011-07-19 08:49:30 +04:00
|
|
|
//
|
2020-07-01 19:03:10 +03:00
|
|
|
// Please see the following page on how to report bugs and issues:
|
2011-07-19 08:49:30 +04:00
|
|
|
//
|
2020-07-01 19:03:10 +03:00
|
|
|
// https://www.fltk.org/bugs.php
|
2011-07-19 08:49:30 +04:00
|
|
|
//
|
|
|
|
|
1998-10-20 17:25:25 +04:00
|
|
|
//
|
|
|
|
// Fullscreen test program for the Fast Light Tool Kit (FLTK).
|
|
|
|
//
|
|
|
|
// This demo shows how to do many of the window manipulations that
|
|
|
|
// are popular on SGI programs, even though X does not really like
|
|
|
|
// them. You can toggle the border on/off, change the visual to
|
|
|
|
// switch between single/double buffer, and make the window take
|
|
|
|
// over the screen.
|
|
|
|
//
|
|
|
|
// Normally the program makes a single window with a child GL window.
|
|
|
|
// This simulates a program where the 3D display is surrounded by
|
|
|
|
// control knobs. Running the program with an argument will
|
|
|
|
// make it make a seperate GL window from the controls window. This
|
|
|
|
// simulates a (older?) style program where the graphics display is
|
|
|
|
// a different window than the controls.
|
|
|
|
//
|
|
|
|
// This program reports how many times it redraws the window to
|
|
|
|
// stdout, so you can see how much time it is wasting. It appears
|
|
|
|
// to be impossible to prevent X from sending redundant resize
|
|
|
|
// events, so there are extra redraws. But the way I have the
|
|
|
|
// code arranged here seems to be keeping that to a minimu.
|
|
|
|
//
|
|
|
|
// Apparently unavoidable bugs:
|
|
|
|
//
|
|
|
|
// Turning the border on causes an unnecessary redraw.
|
|
|
|
//
|
|
|
|
// Turning off full screen when the border is on causes an unnecessary
|
|
|
|
// resize and redraw when the program turns the border on.
|
|
|
|
//
|
2012-06-14 18:36:11 +04:00
|
|
|
// If it is a separate window, turning double buffering on and off
|
1998-10-20 17:25:25 +04:00
|
|
|
// will cause the window to raise, deiconize, and possibly move. You
|
|
|
|
// can avoid this by making the Fl_Gl_Window a child of a normal
|
|
|
|
// window.
|
1998-10-06 22:21:25 +04:00
|
|
|
|
2010-12-15 15:11:16 +03:00
|
|
|
#include <config.h>
|
1998-10-06 22:21:25 +04:00
|
|
|
#include <FL/Fl.H>
|
|
|
|
#include <FL/Fl_Single_Window.H>
|
|
|
|
#include <FL/Fl_Hor_Slider.H>
|
2012-03-23 20:47:53 +04:00
|
|
|
#include <FL/Fl_Input.H>
|
|
|
|
#include <FL/Fl_Menu_Button.H>
|
1998-10-06 22:21:25 +04:00
|
|
|
#include <FL/Fl_Toggle_Light_Button.H>
|
|
|
|
#include <FL/math.h>
|
2012-03-23 20:47:53 +04:00
|
|
|
#include <FL/fl_ask.H>
|
2012-06-14 18:36:11 +04:00
|
|
|
#include <FL/Fl_Browser.H>
|
1998-10-06 22:21:25 +04:00
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#if HAVE_GL
|
|
|
|
#include <FL/gl.h>
|
|
|
|
#include <FL/Fl_Gl_Window.H>
|
|
|
|
|
|
|
|
class shape_window : public Fl_Gl_Window {
|
2022-12-30 21:14:36 +03:00
|
|
|
void draw() FL_OVERRIDE;
|
1998-10-06 22:21:25 +04:00
|
|
|
public:
|
|
|
|
int sides;
|
|
|
|
shape_window(int x,int y,int w,int h,const char *l=0);
|
|
|
|
};
|
|
|
|
|
|
|
|
shape_window::shape_window(int x,int y,int w,int h,const char *l) :
|
|
|
|
Fl_Gl_Window(x,y,w,h,l) {
|
|
|
|
sides = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
void shape_window::draw() {
|
2021-01-29 15:56:09 +03:00
|
|
|
// fprintf(stderr, "drawing size %d %d\n", w(), h());
|
1998-10-06 22:21:25 +04:00
|
|
|
if (!valid()) {
|
|
|
|
valid(1);
|
2021-01-29 15:56:09 +03:00
|
|
|
// fprintf(stderr, "init\n");
|
1998-10-06 22:21:25 +04:00
|
|
|
glLoadIdentity();
|
Changed OpenGL support for the Mac OS X platform: use cocoa instead of deprecated AGL.
All changes are mac-specific, except a very minor change in file src/gl_draw.cxx
where string drawing wrongly claimed to support @symbol, not possible
because symbols are drawn using non-GL primitives.
Unchanged application code can use the new FLTK code.
In addition, the new code allows mac applications to draw OpenGL scenes
at high resolution on so-called 'retina' displays, but this requires some
support from app code. They must call, before opening GL windows,
Fl::use_high_resolution(1);
and change their glViewport() calls as follows
glViewport(0, 0, pxel_w(), pixel_h());
This uses 2 new member functions of the Fl_Gl_Window class,
pixel_w() and pixel_h() returning the window dimensions in pixel
units, that is, twice the w() and h() when the window is mapped
on a retina display.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10498 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
2014-12-20 10:19:23 +03:00
|
|
|
glViewport(0,0,pixel_w(),pixel_h());
|
1998-10-06 22:21:25 +04:00
|
|
|
}
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
2021-08-31 18:18:18 +03:00
|
|
|
glColor3f(.5f, .6f, .7f);
|
1998-10-06 22:21:25 +04:00
|
|
|
glBegin(GL_POLYGON);
|
2007-05-20 04:01:06 +04:00
|
|
|
for (int j = 0; j < sides; j ++) {
|
|
|
|
double ang = j*2*M_PI/sides;
|
2021-08-31 18:18:18 +03:00
|
|
|
glVertex3f((GLfloat)cos(ang), (GLfloat)sin(ang), 0);
|
1998-10-06 22:21:25 +04:00
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#include <FL/fl_draw.H>
|
|
|
|
|
|
|
|
class shape_window : public Fl_Window {
|
2023-11-03 17:34:23 +03:00
|
|
|
void draw() FL_OVERRIDE;
|
1998-10-06 22:21:25 +04:00
|
|
|
public:
|
|
|
|
int sides;
|
|
|
|
shape_window(int x,int y,int w,int h,const char *l=0);
|
|
|
|
};
|
|
|
|
|
|
|
|
shape_window::shape_window(int x,int y,int w,int h,const char *l) :
|
|
|
|
Fl_Window(x,y,w,h,l) {
|
|
|
|
sides = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
void shape_window::draw() {
|
|
|
|
fl_color(0);
|
|
|
|
fl_rectf(0,0,w(),h());
|
|
|
|
fl_font(0,20);
|
|
|
|
fl_color(7);
|
|
|
|
fl_draw("This requires GL",0,0,w(),h(),FL_ALIGN_CENTER);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2012-03-23 20:47:53 +04:00
|
|
|
class fullscreen_window : public Fl_Single_Window {
|
|
|
|
public:
|
|
|
|
fullscreen_window(int W, int H, const char *t=0);
|
2022-12-30 21:14:36 +03:00
|
|
|
int handle (int e) FL_OVERRIDE;
|
2023-11-04 13:30:45 +03:00
|
|
|
void resize(int x, int y, int w, int h) FL_OVERRIDE;
|
|
|
|
Fl_Toggle_Light_Button *b3_maxi;
|
2012-03-23 20:47:53 +04:00
|
|
|
Fl_Toggle_Light_Button *b3;
|
2014-06-11 13:10:53 +04:00
|
|
|
Fl_Toggle_Light_Button *b4;
|
2012-03-23 20:47:53 +04:00
|
|
|
};
|
|
|
|
|
2020-07-01 19:03:10 +03:00
|
|
|
fullscreen_window::fullscreen_window(int W, int H, const char *t) : Fl_Single_Window(W, H, t) {
|
2012-03-23 20:47:53 +04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-11-04 13:30:45 +03:00
|
|
|
void after_resize(void *data) {
|
|
|
|
Fl::remove_check(after_resize, data);
|
|
|
|
fullscreen_window *win = (fullscreen_window*)data;
|
|
|
|
if (win->maximize_active()) win->b3_maxi->set();
|
|
|
|
else win->b3_maxi->clear();
|
|
|
|
win->b3_maxi->redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
void fullscreen_window::resize(int x, int y, int w, int h) {
|
|
|
|
Fl_Single_Window::resize(x,y,w,h);
|
|
|
|
Fl::add_check(after_resize, this);
|
|
|
|
};
|
|
|
|
|
2012-03-23 20:47:53 +04:00
|
|
|
int fullscreen_window::handle(int e) {
|
|
|
|
if (e == FL_FULLSCREEN) {
|
2021-01-29 15:56:09 +03:00
|
|
|
// fprintf(stderr, "Received FL_FULLSCREEN event\n");
|
2012-03-23 20:47:53 +04:00
|
|
|
b3->value(fullscreen_active());
|
|
|
|
}
|
|
|
|
if (Fl_Single_Window::handle(e)) return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1998-10-06 22:21:25 +04:00
|
|
|
void sides_cb(Fl_Widget *o, void *p) {
|
|
|
|
shape_window *sw = (shape_window *)p;
|
|
|
|
sw->sides = int(((Fl_Slider *)o)->value());
|
|
|
|
sw->redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
#if HAVE_GL
|
|
|
|
void double_cb(Fl_Widget *o, void *p) {
|
|
|
|
shape_window *sw = (shape_window *)p;
|
|
|
|
int d = ((Fl_Button *)o)->value();
|
|
|
|
sw->mode(d ? Fl_Mode(FL_DOUBLE|FL_RGB) : FL_RGB);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
void double_cb(Fl_Widget *, void *) {}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void border_cb(Fl_Widget *o, void *p) {
|
|
|
|
Fl_Window *w = (Fl_Window *)p;
|
|
|
|
int d = ((Fl_Button *)o)->value();
|
|
|
|
w->border(d);
|
|
|
|
}
|
|
|
|
|
2023-11-04 13:30:45 +03:00
|
|
|
|
|
|
|
void maximize_cb(Fl_Widget *o, void *p) {
|
|
|
|
Fl_Window *w = (Fl_Window *)p;
|
|
|
|
if (w->maximize_active()) {
|
|
|
|
w->un_maximize();
|
|
|
|
//((Fl_Button*)o)->set();
|
|
|
|
} else {
|
|
|
|
w->maximize();
|
|
|
|
//((Fl_Button*)o)->clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-10-06 22:21:25 +04:00
|
|
|
Fl_Button *border_button;
|
|
|
|
void fullscreen_cb(Fl_Widget *o, void *p) {
|
|
|
|
Fl_Window *w = (Fl_Window *)p;
|
|
|
|
int d = ((Fl_Button *)o)->value();
|
|
|
|
if (d) {
|
|
|
|
w->fullscreen();
|
2018-02-09 17:39:42 +03:00
|
|
|
#ifndef _WIN32 // update our border state in case border was turned off
|
2012-03-23 20:47:53 +04:00
|
|
|
border_button->value(w->border());
|
|
|
|
#endif
|
1998-10-06 22:21:25 +04:00
|
|
|
} else {
|
2012-03-23 20:47:53 +04:00
|
|
|
w->fullscreen_off();
|
1998-10-06 22:21:25 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-11 13:10:53 +04:00
|
|
|
void allscreens_cb(Fl_Widget *o, void *p) {
|
|
|
|
Fl_Window *w = (Fl_Window *)p;
|
|
|
|
int d = ((Fl_Button *)o)->value();
|
|
|
|
if (d) {
|
|
|
|
int top, bottom, left, right;
|
|
|
|
int top_y, bottom_y, left_x, right_x;
|
|
|
|
|
|
|
|
int sx, sy, sw, sh;
|
|
|
|
|
|
|
|
top = bottom = left = right = 0;
|
|
|
|
|
|
|
|
Fl::screen_xywh(sx, sy, sw, sh, 0);
|
|
|
|
top_y = sy;
|
|
|
|
bottom_y = sy + sh;
|
|
|
|
left_x = sx;
|
|
|
|
right_x = sx + sw;
|
|
|
|
|
|
|
|
for (int i = 1;i < Fl::screen_count();i++) {
|
|
|
|
Fl::screen_xywh(sx, sy, sw, sh, i);
|
|
|
|
if (sy < top_y) {
|
|
|
|
top = i;
|
|
|
|
top_y = sy;
|
|
|
|
}
|
|
|
|
if ((sy + sh) > bottom_y) {
|
|
|
|
bottom = i;
|
|
|
|
bottom_y = sy + sh;
|
|
|
|
}
|
|
|
|
if (sx < left_x) {
|
|
|
|
left = i;
|
|
|
|
left_x = sx;
|
|
|
|
}
|
|
|
|
if ((sx + sw) > right_x) {
|
|
|
|
right = i;
|
|
|
|
right_x = sx + sw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
w->fullscreen_screens(top, bottom, left, right);
|
|
|
|
} else {
|
|
|
|
w->fullscreen_screens(-1, -1, -1, -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-14 19:09:46 +04:00
|
|
|
void update_screeninfo(Fl_Widget *b, void *p) {
|
|
|
|
Fl_Browser *browser = (Fl_Browser *)p;
|
2012-06-14 18:36:11 +04:00
|
|
|
int x, y, w, h;
|
|
|
|
char line[128];
|
|
|
|
browser->clear();
|
|
|
|
|
2022-09-26 17:12:18 +03:00
|
|
|
snprintf(line, sizeof(line), "Main screen work area: %dx%d@%d,%d", Fl::w(), Fl::h(), Fl::x(), Fl::y());
|
2012-06-14 18:36:11 +04:00
|
|
|
browser->add(line);
|
|
|
|
Fl::screen_work_area(x, y, w, h);
|
2022-09-26 17:12:18 +03:00
|
|
|
snprintf(line, sizeof(line), "Mouse screen work area: %dx%d@%d,%d", w, h, x, y);
|
2012-06-14 18:36:11 +04:00
|
|
|
browser->add(line);
|
|
|
|
for (int n = 0; n < Fl::screen_count(); n++) {
|
2020-07-01 19:03:10 +03:00
|
|
|
int x, y, w, h;
|
2016-06-22 11:36:48 +03:00
|
|
|
float dpih, dpiv;
|
2020-07-01 19:03:10 +03:00
|
|
|
Fl::screen_xywh(x, y, w, h, n);
|
2016-06-22 11:36:48 +03:00
|
|
|
Fl::screen_dpi(dpih, dpiv, n);
|
2022-09-26 17:12:18 +03:00
|
|
|
snprintf(line, sizeof(line), "Screen %d: %dx%d@%d,%d DPI:%.1fx%.1f scale:%.2f", n, w, h, x, y, dpih, dpiv, Fl::screen_scale(n));
|
2020-07-01 19:03:10 +03:00
|
|
|
browser->add(line);
|
|
|
|
Fl::screen_work_area(x, y, w, h, n);
|
2022-09-26 17:12:18 +03:00
|
|
|
snprintf(line, sizeof(line), "Work area %d: %dx%d@%d,%d", n, w, h, x, y);
|
2020-07-01 19:03:10 +03:00
|
|
|
browser->add(line);
|
2012-06-14 18:36:11 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-10-06 22:21:25 +04:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
void exit_cb(Fl_Widget *, void *) {
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2023-11-04 13:30:45 +03:00
|
|
|
#define NUMB 9
|
1998-10-06 22:21:25 +04:00
|
|
|
|
|
|
|
int twowindow = 0;
|
|
|
|
int initfull = 0;
|
|
|
|
int arg(int, char **argv, int &i) {
|
|
|
|
if (argv[i][1] == '2') {twowindow = 1; i++; return 1;}
|
|
|
|
if (argv[i][1] == 'f') {initfull = 1; i++; return 1;}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
|
Changed OpenGL support for the Mac OS X platform: use cocoa instead of deprecated AGL.
All changes are mac-specific, except a very minor change in file src/gl_draw.cxx
where string drawing wrongly claimed to support @symbol, not possible
because symbols are drawn using non-GL primitives.
Unchanged application code can use the new FLTK code.
In addition, the new code allows mac applications to draw OpenGL scenes
at high resolution on so-called 'retina' displays, but this requires some
support from app code. They must call, before opening GL windows,
Fl::use_high_resolution(1);
and change their glViewport() calls as follows
glViewport(0, 0, pxel_w(), pixel_h());
This uses 2 new member functions of the Fl_Gl_Window class,
pixel_w() and pixel_h() returning the window dimensions in pixel
units, that is, twice the w() and h() when the window is mapped
on a retina display.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10498 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
2014-12-20 10:19:23 +03:00
|
|
|
Fl::use_high_res_GL(1);
|
1998-10-06 22:21:25 +04:00
|
|
|
int i=0;
|
|
|
|
if (Fl::args(argc,argv,i,arg) < argc)
|
|
|
|
Fl::fatal("Options are:\n -2 = 2 windows\n -f = startup fullscreen\n%s",Fl::help);
|
|
|
|
|
2019-03-06 16:54:51 +03:00
|
|
|
fullscreen_window window(460,400+30*NUMB); window.end();
|
1998-10-06 22:21:25 +04:00
|
|
|
|
2012-06-14 18:36:11 +04:00
|
|
|
shape_window sw(10,10,window.w()-20,window.h()-30*NUMB-120);
|
2020-02-09 10:43:36 +03:00
|
|
|
sw.set_visible(); // necessary because sw is not a child of window
|
1998-10-06 22:21:25 +04:00
|
|
|
#if HAVE_GL
|
|
|
|
sw.mode(FL_RGB);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Fl_Window *w;
|
2020-07-01 19:03:10 +03:00
|
|
|
if (twowindow) { // make it's own window
|
1998-10-06 22:21:25 +04:00
|
|
|
sw.resizable(&sw);
|
|
|
|
w = &sw;
|
2020-07-01 19:03:10 +03:00
|
|
|
window.set_modal(); // makes controls stay on top when fullscreen pushed
|
1998-10-06 22:21:25 +04:00
|
|
|
argc--;
|
|
|
|
sw.show();
|
2020-07-01 19:03:10 +03:00
|
|
|
} else { // otherwise make a subwindow
|
1998-10-06 22:21:25 +04:00
|
|
|
window.add(sw);
|
|
|
|
window.resizable(&sw);
|
|
|
|
w = &window;
|
|
|
|
}
|
|
|
|
|
|
|
|
window.begin();
|
|
|
|
|
2012-06-14 18:36:11 +04:00
|
|
|
int y = window.h()-30*NUMB-105;
|
1998-10-06 22:21:25 +04:00
|
|
|
Fl_Hor_Slider slider(50,y,window.w()-60,30,"Sides:");
|
|
|
|
slider.align(FL_ALIGN_LEFT);
|
|
|
|
slider.callback(sides_cb,&sw);
|
|
|
|
slider.value(sw.sides);
|
|
|
|
slider.step(1);
|
|
|
|
slider.bounds(3,40);
|
|
|
|
y+=30;
|
|
|
|
|
|
|
|
Fl_Toggle_Light_Button b1(50,y,window.w()-60,30,"Double Buffered");
|
|
|
|
b1.callback(double_cb,&sw);
|
|
|
|
y+=30;
|
|
|
|
|
2012-03-23 20:47:53 +04:00
|
|
|
Fl_Input i1(50,y,window.w()-60,30, "Input");
|
|
|
|
y+=30;
|
|
|
|
|
1998-10-06 22:21:25 +04:00
|
|
|
Fl_Toggle_Light_Button b2(50,y,window.w()-60,30,"Border");
|
|
|
|
b2.callback(border_cb,w);
|
|
|
|
b2.set();
|
|
|
|
border_button = &b2;
|
|
|
|
y+=30;
|
|
|
|
|
2012-03-23 20:47:53 +04:00
|
|
|
window.b3 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"FullScreen");
|
|
|
|
window.b3->callback(fullscreen_cb,w);
|
1998-10-06 22:21:25 +04:00
|
|
|
y+=30;
|
2023-11-14 20:14:48 +03:00
|
|
|
|
2023-11-04 13:30:45 +03:00
|
|
|
window.b3_maxi = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"Maximize");
|
|
|
|
window.b3_maxi->callback(maximize_cb,w);
|
|
|
|
y+=30;
|
1998-10-06 22:21:25 +04:00
|
|
|
|
2014-06-11 13:10:53 +04:00
|
|
|
window.b4 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"All Screens");
|
|
|
|
window.b4->callback(allscreens_cb,w);
|
|
|
|
y+=30;
|
|
|
|
|
1998-10-06 22:21:25 +04:00
|
|
|
Fl_Button eb(50,y,window.w()-60,30,"Exit");
|
|
|
|
eb.callback(exit_cb);
|
|
|
|
y+=30;
|
|
|
|
|
2012-06-14 19:09:46 +04:00
|
|
|
Fl_Browser *browser = new Fl_Browser(50,y,window.w()-60,100);
|
|
|
|
update_screeninfo(0, browser);
|
2012-06-14 18:36:11 +04:00
|
|
|
y+=100;
|
2020-07-01 19:03:10 +03:00
|
|
|
|
2012-06-14 19:09:46 +04:00
|
|
|
Fl_Button update(50,y,window.w()-60,30,"Update");
|
|
|
|
update.callback(update_screeninfo, browser);
|
|
|
|
y+=30;
|
2012-06-14 18:36:11 +04:00
|
|
|
|
2012-03-23 20:47:53 +04:00
|
|
|
if (initfull) {window.b3->set(); window.b3->do_callback();}
|
1998-10-06 22:21:25 +04:00
|
|
|
|
|
|
|
window.end();
|
|
|
|
window.show(argc,argv);
|
2020-07-01 19:03:10 +03:00
|
|
|
|
2012-06-14 19:09:46 +04:00
|
|
|
return Fl::run();
|
1998-10-06 22:21:25 +04:00
|
|
|
}
|