Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/ui/ui.c
diff options
context:
space:
mode:
authorBernie Innocenti <bernie@codewiz.org>2010-05-03 21:53:47 (GMT)
committer Bernie Innocenti <bernie@codewiz.org>2010-05-03 21:53:47 (GMT)
commit1030dc837b10a03a02a85d5504cbeec168ce49e2 (patch)
tree698eefa87ac437deaf36a4141b326f8ce7986692 /src/ui/ui.c
Import XaoS r489 (trunk after version 3.5)
Diffstat (limited to 'src/ui/ui.c')
-rw-r--r--src/ui/ui.c1761
1 files changed, 1761 insertions, 0 deletions
diff --git a/src/ui/ui.c b/src/ui/ui.c
new file mode 100644
index 0000000..413d357
--- /dev/null
+++ b/src/ui/ui.c
@@ -0,0 +1,1761 @@
+/*
+ * XaoS, a fast portable realtime fractal zoomer
+ * Copyright (C) 1996 by
+ *
+ * Jan Hubicka (hubicka@paru.cas.cz)
+ * Thomas Marsh (tmarsh@austin.ibm.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 of the License, 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.
+ */
+#include <config.h>
+#undef _EFENCE_
+#ifdef _plan9_
+#include <u.h>
+#include <libc.h>
+#include <ctype.h>
+#else
+#include <limits.h>
+#include <aconfig.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#ifdef __EMX__
+#include <float.h>
+#endif
+#ifdef __EMX__
+#include <sys/types.h>
+#endif
+#ifndef _MAC
+#include <sys/stat.h>
+#endif
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <signal.h>
+#endif
+#include <fconfig.h>
+#ifndef _plan9_
+#include <assert.h>
+#endif
+#include <filter.h>
+#include <ui_helper.h>
+#include <ui.h>
+#include <param.h>
+#include <version.h>
+#include <timers.h>
+#include <plane.h>
+#include <xthread.h>
+#include <xerror.h>
+#include <xmenu.h>
+#include <grlib.h>
+#include <archaccel.h>
+#include "uiint.h"
+#ifdef HAVE_GETTEXT
+#include <libintl.h>
+#include <locale.h>
+#else
+#define gettext(STRING) STRING
+#endif
+
+#ifdef SFFE_USING
+#include "sffe.h"
+#endif
+
+#ifdef DESTICKY
+int euid, egid;
+#endif
+#ifdef DEBUG
+#ifdef __linux__
+#include <malloc.h>
+#define MEMCHECK
+#endif
+#endif
+#define textheight1 (driver->textheight)
+#define textwidth1 (driver->textwidth)
+#define ui_flush() (driver->flush?driver->flush(),1:0)
+#ifdef MEMCHECK
+#define STATUSLINES 13
+#else
+#define STATUSLINES 11
+#endif
+static void ui_mouse(int mousex, int mousey, int mousebuttons,
+ int iterchange);
+#ifndef exit_xaos
+#define exit_xaos(i) exit(i)
+#endif
+
+xio_pathdata configfile;
+static void ui_unregistermenus(void);
+static void ui_mkimages(int, int);
+static void ui_mainloop(int loop);
+
+int prog_argc;
+int err;
+char **prog_argv;
+/*UI state */
+uih_context *uih;
+CONST struct ui_driver *driver;
+char statustext[256];
+int ui_nogui;
+static struct image *image;
+static int statusstart;
+static struct uih_window *statuswindow = NULL;
+static int ministatusstart;
+static struct uih_window *ministatuswindow = NULL;
+static int mouse;
+/* Used by ui_mouse */
+static int dirty = 0;
+static int lastiter;
+static int maxiter;
+static int lastbuttons, lastx, lasty;
+static int callresize = 0;
+static tl_timer *maintimer;
+static tl_timer *arrowtimer;
+static tl_timer *loopt;
+static int todriver = 0;
+
+/* Command line variables */
+static char *defpipe;
+static char *defdriver = NULL;
+static int deflist;
+static int printconfig;
+static int printspeed;
+static int delaytime = 0;
+static int defthreads = 0;
+static int maxframerate = 80;
+static float defscreenwidth = 0.0, defscreenheight = 0.0, defpixelwidth =
+ 0.0, defpixelheight = 0.0;
+
+#ifdef SFFE_USING
+char *sffeform = NULL;
+char *sffeinit = NULL;
+#endif
+
+CONST struct params global_params[] = {
+ {"-delay", P_NUMBER, &delaytime,
+ "Delay screen updates (milliseconds)"},
+ {"-driver", P_STRING, &defdriver, "Select driver"},
+ {"-list", P_SWITCH, &deflist, "List available drivers. Then exit"},
+ {"-config", P_SWITCH, &printconfig, "Print configuration. Then exit"},
+ {"-speedtest", P_SWITCH, &printspeed,
+ "Test speed of calculation loop. Then exit"},
+#ifndef nthreads
+ {"-threads", P_NUMBER, &defthreads,
+ "Set number of threads (CPUs) to use"},
+#else
+ {"-threads", P_NUMBER, &defthreads,
+ "Multiple CPUs unsupported - please recompile XaoS with threads enabled"},
+#endif
+#ifdef COMPILE_PIPE
+ {"-pipe", P_STRING, &defpipe,
+ "Accept commands from pipe (use \"-\" for stdin)"},
+#else
+ {"-pipe", P_STRING, &defpipe,
+ "Pipe input unavailable (recompile XaoS)"},
+#endif
+ {"-maxframerate", P_NUMBER, &maxframerate,
+ "Maximal framerate (0 for unlimited - default)"},
+ {"", P_HELP, NULL,
+ "Screen size options: \n\n Knowledge of exact screen size makes random dot stereogram look better. \n Also is used for choosing correct view area"},
+ {"-screenwidth", P_FLOAT, &defscreenwidth,
+ "exact size of screen in centimeters"},
+ {"-screenheight", P_FLOAT, &defscreenheight,
+ "exact size of screen in centimeters"},
+ {"", P_HELP, NULL,
+ " Use this option in case you use some kind of virtual screen\n or something similiar that confuses previous options"},
+ {"-pixelwidth", P_FLOAT, &defpixelwidth,
+ "exact size of one pixel in centimeters"},
+ {"-pixelheight", P_FLOAT, &defpixelheight,
+ "exact size of one pixel in centimeters"},
+#ifdef SFFE_USING
+ {"-formula", P_STRING, &sffeform,
+ "user formula"},
+ {"-forminit", P_STRING, &sffeinit,
+ "z0 for user formula"},
+#endif
+ {NULL, 0, NULL, NULL}
+};
+
+static int resizeregistered = 0;
+static void ui_updatemenus(uih_context * c, CONST char *name)
+{
+ CONST struct menuitem *item;
+ if (ui_nogui) {
+ if (name == NULL) {
+ printf("Root \"%s\"", uih->menuroot);
+ }
+ item = menu_findcommand(name);
+ if (item == NULL) {
+ /*x_fatalerror ("Internall error:unknown command %s", name); */
+ return;
+ }
+ if (item->flags & MENUFLAG_CHECKBOX) {
+ if (menu_enabled(item, c))
+ printf("checkbox \"%s\" on\n", name);
+ else
+ printf("checkbox \"%s\" off\n", name);
+ }
+ if (item->flags & MENUFLAG_RADIO) {
+ if (menu_enabled(item, c))
+ printf("radio \"%s\"\n", name);
+ }
+ }
+ if (driver != NULL && driver->gui_driver) {
+ if (name == NULL) {
+ if (driver->gui_driver->setrootmenu)
+ driver->gui_driver->setrootmenu(c, uih->menuroot);
+ return;
+ }
+ item = menu_findcommand(name);
+ if (item == NULL) {
+ /*fprintf (stderr, "Internall error:unknown command %s\n", name); */
+ return;
+ }
+ if (item->flags & (MENUFLAG_CHECKBOX | MENUFLAG_RADIO)) {
+ if (driver->gui_driver->enabledisable)
+ driver->gui_driver->enabledisable(uih, name);
+ }
+ }
+}
+
+static void mousetype(int m)
+{
+#ifdef _plan9_
+#define filevisible 0
+#endif
+ if (ui_nmenus || helpvisible || filevisible || dialogvisible
+ || yesnodialogvisible)
+ m = NORMALMOUSE;
+ if (mouse != m) {
+ mouse = m;
+ if (driver->mousetype != NULL)
+ driver->mousetype(m);
+ }
+}
+
+static void ui_display(void)
+{
+ if (nthreads == 1)
+ uih_drawwindows(uih);
+ driver->display();
+ uih_cycling_continue(uih);
+ if (!(driver->flags & NOFLUSHDISPLAY))
+ ui_flush();
+}
+
+float ui_get_windowwidth(int width)
+{
+ if (defscreenwidth > 0.0 && driver->flags & RESOLUTION)
+ return (defscreenwidth * width / driver->maxwidth);
+ if (defscreenwidth > 0.0)
+ return (defscreenwidth);
+ if (defpixelwidth > 0.0)
+ return (defpixelwidth * width);
+ return (0);
+}
+
+static float get_windowwidth(int width)
+{
+ float w = ui_get_windowwidth(width);
+ if (w)
+ return w;
+ if (driver->flags & PIXELSIZE)
+ return (driver->width * width);
+ if (driver->flags & SCREENSIZE)
+ return (driver->width);
+ if (driver->flags & RESOLUTION)
+ return (29.0 / driver->maxwidth * width);
+ return (29.0);
+}
+
+float ui_get_windowheight(int height)
+{
+ if (defscreenheight > 0.0 && driver->flags & RESOLUTION)
+ return (defscreenheight * height / driver->maxheight);
+ if (defscreenheight > 0.0)
+ return (defscreenheight);
+ if (defpixelheight > 0.0)
+ return (defpixelheight * height);
+ return 0;
+}
+
+static float get_windowheight(int height)
+{
+ float h = ui_get_windowheight(height);
+ if (h)
+ return h;
+ if (driver->flags & PIXELSIZE)
+ return (driver->height * height);
+ if (driver->flags & SCREENSIZE)
+ return (driver->height);
+ if (driver->flags & RESOLUTION)
+ return (21.0 / driver->maxheight * height);
+ return (21.5);
+}
+
+extern int dynsize;
+static void ui_outofmem(void)
+{
+ x_error(gettext("XaoS is out of memory."));
+}
+
+#define CHECKPROCESSEVENTS(b,k) assert(!((k)&~15)&&!((b)&~(BUTTON1|BUTTON2|BUTTON3)))
+static int
+ui_passfunc(struct uih_context *c, int display, CONST char *text,
+ float percent)
+{
+ char str[80];
+ int x = 0, y = 0, b = 0, k = 0;
+ driver->processevents(0, &x, &y, &b, &k);
+ ui_mouse(x, y, b, k);
+ CHECKPROCESSEVENTS(b, k);
+ if (!uih->play) {
+ if (uih->display)
+ ui_display(), display = 1;
+ if (!c->interruptiblemode && !uih->play) {
+ if (display) {
+ if (percent)
+ sprintf(str, "%s %3.2f%% ", text,
+ (double) percent);
+ else
+ sprintf(str, "%s ", text);
+ driver->print(0, uih->image->height - textheight1, str);
+ ui_flush();
+ }
+ } else {
+ if (!(driver->flags & NOFLUSHDISPLAY))
+ ui_flush();
+ }
+ }
+ return (0);
+}
+
+static void ui_updatestatus(void)
+{
+ double times =
+ (uih->fcontext->currentformula->v.rr) / (uih->fcontext->s.rr);
+ double timesnop = log(times) / log(10.0);
+ double speed;
+ uih_drawwindows(uih);
+ driver->display();
+ uih_cycling_continue(uih);
+ speed = uih_displayed(uih);
+ sprintf(statustext,
+ gettext
+ ("%s %.2f times (%.1fE) %2.2f frames/sec %c %i %i %i %i "),
+ times < 1 ? gettext("unzoomed") : gettext("zoomed"),
+ times < 1 ? 1.0 / times : times, timesnop, speed,
+ uih->autopilot ? 'A' : ' ', uih->fcontext->coloringmode + 1,
+ uih->fcontext->incoloringmode + 1, uih->fcontext->plane + 1,
+ uih->fcontext->maxiter);
+
+ if (!(driver->flags & NOFLUSHDISPLAY))
+ ui_flush();
+ STAT(printf(gettext("framerate:%f\n"), speed));
+ driver->print(0, 0, "");
+}
+
+void ui_updatestarts(void)
+{
+ int y = 0;
+ y += ui_menuwidth();
+ ministatusstart = y;
+ if (ministatuswindow != NULL)
+ y += xtextheight(uih->font);
+ statusstart = y;
+ if (statuswindow != NULL)
+ y += xtextheight(uih->font) * STATUSLINES;
+ uih->messg.messagestart = y;
+}
+
+void ui_menuactivate(CONST menuitem * item, dialogparam * d)
+{
+ if (item == NULL)
+ return;
+ ui_closemenus();
+ if (item->type == MENU_SUBMENU) {
+ ui_menu(item->shortname);
+ return;
+ } else {
+ if (menu_havedialog(item, uih) && d == NULL) {
+ ui_builddialog(item);
+ return;
+ }
+ if (uih->incalculation && !(item->flags & MENUFLAG_INCALC)) {
+ menu_addqueue(item, d);
+ if (item->flags & MENUFLAG_INTERRUPT)
+ uih_interrupt(uih);
+ return;
+ }
+ if (item->flags & MENUFLAG_CHECKBOX) {
+ char s[256];
+ ui_updatestatus();
+ if (!menu_enabled(item, uih))
+ sprintf(s, gettext("Enabling: %s. "), item->name);
+ else
+ sprintf(s, gettext("Disabling: %s. "), item->name);
+ uih_message(uih, s);
+ ui_flush();
+ } else
+ uih_message(uih, item->name);
+ uih_saveundo(uih);
+ menu_activate(item, uih, d);
+ if (d != NULL)
+ menu_destroydialog(item, d, uih);
+ }
+}
+
+xio_path ui_getfile(CONST char *basename, CONST char *extension)
+{
+ return (xio_getfilename(basename, extension));
+}
+
+static void
+ui_statuspos(uih_context * uih, int *x, int *y, int *w, int *h, void *data)
+{
+ *x = 0;
+ *y = statusstart;
+ *w = uih->image->width;
+ *h = xtextheight(uih->font) * STATUSLINES;
+}
+
+static void ui_drawstatus(uih_context * uih, void *data)
+{
+ char str[6000];
+ int h = xtextheight(uih->font);
+ sprintf(str, gettext("Fractal name:%s"),
+ uih->fcontext->currentformula->name[!uih->fcontext->
+ mandelbrot]);
+ xprint(uih->image, uih->font, 0, statusstart, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, gettext("Fractal type:%s"),
+ uih->
+ fcontext->mandelbrot ? gettext("Mandelbrot") :
+ gettext("Julia"));
+#ifdef SFFE_USING
+ if (uih->fcontext->currentformula->flags & SFFE_FRACTAL) {
+ sprintf(str, gettext("Formula:%s"), uih->parser->expression);
+ };
+#endif
+ xprint(uih->image, uih->font, 0, statusstart + h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, gettext("View:[%1.12f,%1.12f]"),
+ (double) uih->fcontext->s.cr, (double) uih->fcontext->s.ci);
+ xprint(uih->image, uih->font, 0, statusstart + 2 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, gettext("size:[%1.12f,%1.12f]"),
+ (double) uih->fcontext->s.rr, (double) uih->fcontext->s.ri);
+ xprint(uih->image, uih->font, 0, statusstart + 3 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, gettext("Rotation:%4.2f Screen size:%i:%i"),
+ (double) uih->fcontext->angle, uih->image->width,
+ uih->image->height);
+ xprint(uih->image, uih->font, 0, statusstart + 4 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, gettext("Iterations:%-4i Palette size:%i"),
+ uih->fcontext->maxiter, uih->image->palette->size);
+ xprint(uih->image, uih->font, 0, statusstart + 5 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, "Bailout:%4.2f", (double) uih->fcontext->bailout);
+ xprint(uih->image, uih->font, 0, statusstart + 6 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, gettext("Autopilot:%-4s Plane:%s"),
+ uih->autopilot ? gettext("On") : gettext("Off"),
+ planename[uih->fcontext->plane]);
+ xprint(uih->image, uih->font, 0, statusstart + 7 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, gettext("incoloring:%s outcoloring:%s"),
+ incolorname[uih->fcontext->incoloringmode],
+ outcolorname[uih->fcontext->coloringmode]);
+ xprint(uih->image, uih->font, 0, statusstart + 8 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, gettext("zoomspeed:%f"), (float) uih->maxstep * 1000);
+ xprint(uih->image, uih->font, 0, statusstart + 9 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ if (uih->fcontext->mandelbrot)
+ strcpy(str, gettext("Parameter:none"));
+ else
+ sprintf(str, gettext("Parameter:[%f,%f]"),
+ (float) uih->fcontext->pre, (float) uih->fcontext->pim);
+ xprint(uih->image, uih->font, 0, statusstart + 10 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+#ifdef MEMCHECK
+ {
+ struct mallinfo i = mallinfo();
+ sprintf(str, "Allocated arena:%i Wasted:%i %i", i.arena, i.ordblks,
+ i.fordblks);
+ xprint(uih->image, uih->font, 0, statusstart + 11 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ sprintf(str, "Mmaped blocks%i Mmaped area:%i keep:%i", i.hblks,
+ i.hblkhd, i.keepcost);
+ xprint(uih->image, uih->font, 0, statusstart + 12 * h, str,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+ }
+#endif
+ ui_flush();
+}
+
+static void ui_status(uih_context * uih)
+{
+ if (statuswindow == NULL) {
+ statuswindow =
+ uih_registerw(uih, ui_statuspos, ui_drawstatus, NULL, 0);
+ } else {
+ uih_removew(uih, statuswindow);
+ statuswindow = NULL;
+ }
+ ui_updatemenus(uih, "status");
+ ui_updatemenus(uih, "animministatus");
+ ui_updatestarts();
+}
+
+static int ui_statusenabled(uih_context * uih)
+{
+ return (statuswindow != NULL);
+}
+
+static void
+ui_ministatuspos(uih_context * uih, int *x, int *y, int *w, int *h,
+ void *data)
+{
+ *x = 0;
+ *y = ministatusstart;
+ *w = uih->image->width;
+ *h = xtextheight(uih->font);
+}
+
+static void ui_drawministatus(uih_context * uih, void *data)
+{
+ xprint(uih->image, uih->font, 0, ministatusstart, statustext,
+ FGCOLOR(uih), BGCOLOR(uih), 0);
+}
+
+static void ui_noguisw(uih_context * uih)
+{
+ ui_nogui ^= 1;
+ ui_updatemenus(uih, "nogui");
+}
+
+static int ui_noguienabled(uih_context * uih)
+{
+ return (ui_nogui);
+}
+
+static void ui_ministatus(uih_context * uih)
+{
+ if (ministatuswindow == NULL) {
+ ministatuswindow =
+ uih_registerw(uih, ui_ministatuspos, ui_drawministatus, NULL,
+ 0);
+ } else {
+ uih_removew(uih, ministatuswindow);
+ ministatuswindow = NULL;
+ }
+ ui_updatestarts();
+ ui_updatemenus(uih, "ministatus");
+ ui_updatemenus(uih, "animministatus");
+}
+
+static int ui_ministatusenabled(uih_context * uih)
+{
+ return (ministatuswindow != NULL);
+}
+
+static void ui_message(struct uih_context *u)
+{
+ char s[80];
+ if (uih->play)
+ return;
+ mousetype(WAITMOUSE);
+ sprintf(s, gettext("Please wait while calculating %s"),
+ uih->fcontext->currentformula->name[!uih->fcontext->
+ mandelbrot]);
+ driver->print(0, 0, s);
+}
+
+#define ROTATESPEEDUP 30
+static int
+procescounter(int *counter, CONST char *text, int speed, int keys,
+ int lastkeys, int down, int up, int tenskip, int min,
+ int max)
+{
+ static int pid = -1;
+ int changed = 0;
+ char str[80];
+ if (tl_lookup_timer(arrowtimer) > 1000000)
+ tl_reset_timer(arrowtimer);
+ if ((keys & up) && !(lastkeys & up)) {
+ (*counter)++;
+ tenskip = 0;
+ changed = 1;
+ tl_reset_timer(arrowtimer);
+ }
+ if ((keys & down) && !(lastkeys & down)) {
+ (*counter)--;
+ tenskip = 0;
+ changed = 1;
+ tl_reset_timer(arrowtimer);
+ }
+ while (tl_lookup_timer(arrowtimer) > speed * FRAMETIME) {
+ tl_slowdown_timer(arrowtimer, speed * FRAMETIME);
+ if (keys & up) {
+ if (tenskip && !(*counter % 10))
+ (*counter) += 10;
+ else
+ (*counter)++;
+ changed = 1;
+ }
+ if (keys & down) {
+ if (tenskip && !(*counter % 10))
+ (*counter) -= 10;
+ else
+ (*counter)--;
+ changed = 1;
+ }
+ }
+ if (changed) {
+ if (*counter > max)
+ *counter = max;
+ if (*counter < min)
+ *counter = min;
+ sprintf(str, text, *counter);
+ uih_rmmessage(uih, pid);
+ pid = uih_message(uih, str);
+ ui_flush();
+ }
+ return changed;
+}
+
+static void
+ui_mouse(int mousex, int mousey, int mousebuttons, int iterchange)
+{
+ int flags;
+ char str[80];
+ static int spid;
+ flags = 0;
+ if (mousex != lastx || mousey != lasty)
+ flags |= MOUSE_MOVE;
+ if ((mousebuttons & BUTTON1) && !(lastbuttons & BUTTON1))
+ flags |= MOUSE_PRESS;
+ if (!(mousebuttons & BUTTON1) && (lastbuttons & BUTTON1))
+ flags |= MOUSE_RELEASE;
+ if (mousebuttons & BUTTON1)
+ flags |= MOUSE_DRAG;
+ lastx = mousex;
+ lasty = mousey;
+ lastbuttons = mousebuttons;
+ tl_update_time();
+ CHECKPROCESSEVENTS(mousebuttons, iterchange);
+ if (ui_helpmouse(mousex, mousey, mousebuttons, flags)) {
+ uih_update(uih, mousex, mousey, 0);
+ return;
+ }
+#ifndef _plan9_
+ if (ui_mousefilesel(mousex, mousey, mousebuttons, flags)) {
+ uih_update(uih, mousex, mousey, 0);
+ return;
+ }
+#endif
+ if (ui_dialogmouse(mousex, mousey, mousebuttons, flags)) {
+ uih_update(uih, mousex, mousey, 0);
+ return;
+ }
+ if (ui_menumouse(mousex, mousey, mousebuttons, flags)) {
+ uih_update(uih, mousex, mousey, 0);
+ return;
+ }
+ uih_update(uih, mousex, mousey, mousebuttons);
+ if (uih->play) {
+ procescounter(&uih->letterspersec,
+ gettext("Letters per second %i "), 2, iterchange,
+ lastiter, 1, 2, 0, 1, INT_MAX);
+ return;
+ }
+ if (!uih->cycling) {
+ if (uih->rotatemode == ROTATE_CONTINUOUS) {
+ static int rpid;
+ if (iterchange == 2) {
+ uih->rotationspeed +=
+ ROTATESPEEDUP * tl_lookup_timer(maintimer) / 1000000.0;
+ uih_rmmessage(uih, rpid);
+ sprintf(str,
+ gettext
+ ("Rotation speed:%2.2f degrees per second "),
+ (float) uih->rotationspeed);
+ rpid = uih_message(uih, str);
+ ui_flush();
+ }
+ if (iterchange == 1) {
+ uih->rotationspeed -=
+ ROTATESPEEDUP * tl_lookup_timer(maintimer) / 1000000.0;
+ uih_rmmessage(uih, rpid);
+ sprintf(str,
+ gettext
+ ("Rotation speed:%2.2f degrees per second "),
+ (float) uih->rotationspeed);
+ rpid = uih_message(uih, str);
+ ui_flush();
+ }
+ tl_reset_timer(maintimer);
+ } else {
+ if (!dirty)
+ maxiter = uih->fcontext->maxiter;
+ if (procescounter
+ (&maxiter, gettext("Iterations: %i "), 1, iterchange,
+ lastiter, 1, 2, 1, 1, INT_MAX) || (iterchange & 3)) {
+ dirty = 1;
+ lastiter = iterchange;
+ return;
+ }
+ }
+ }
+ if (dirty) {
+ if (uih->incalculation)
+ uih_interrupt(uih);
+ else
+ uih_setmaxiter(uih, maxiter), dirty = 0;
+ }
+ if (uih->cycling) {
+ if (procescounter
+ (&uih->cyclingspeed, gettext("Cycling speed: %i "), 1,
+ iterchange, lastiter, 1, 2, 0, -1000000, INT_MAX)) {
+ uih_setcycling(uih, uih->cyclingspeed);
+ }
+ }
+ if (iterchange & 4
+ && (tl_lookup_timer(maintimer) > FRAMETIME || mousebuttons)) {
+ double mul1 = tl_lookup_timer(maintimer) / FRAMETIME;
+ double su = 1 + (SPEEDUP - 1) * mul1;
+ if (su > 2 * SPEEDUP)
+ su = SPEEDUP;
+ tl_reset_timer(maintimer);
+ uih->speedup *= su, uih->maxstep *= su;
+ sprintf(str, gettext("speed:%2.2f "),
+ (double) uih->speedup * (1.0 / STEP));
+ uih_rmmessage(uih, spid);
+ spid = uih_message(uih, str);
+ ui_flush();
+ }
+ if (iterchange & 8
+ && (tl_lookup_timer(maintimer) > FRAMETIME || mousebuttons)) {
+ double mul1 = tl_lookup_timer(maintimer) / FRAMETIME;
+ double su = 1 + (SPEEDUP - 1) * mul1;
+ if (su > 2 * SPEEDUP)
+ su = SPEEDUP;
+ tl_reset_timer(maintimer);
+ uih->speedup /= su, uih->maxstep /= su;
+ sprintf(str, gettext("speed:%2.2f "),
+ (double) uih->speedup * (1 / STEP));
+ uih_rmmessage(uih, spid);
+ spid = uih_message(uih, str);
+ ui_flush();
+ }
+ lastiter = iterchange;
+ return;
+}
+
+void ui_call_resize(void)
+{
+ callresize = 1;
+ uih_interrupt(uih);
+}
+
+static int
+ui_alloccolor(struct palette *pal, int init, int r, int g, int b)
+{
+ int i;
+ i = driver->set_color(r, g, b, init);
+ if (i == -1)
+ return (-1);
+ if (init)
+ pal->size = 0;
+ pal->pixels[pal->size] = i;
+ pal->rgb[i][0] = r;
+ pal->rgb[i][1] = g;
+ pal->rgb[i][2] = b;
+ pal->size++;
+ if (driver->flags & UPDATE_AFTER_PALETTE) {
+ uih->display = 1;
+ }
+ return (i);
+}
+
+static void
+ui_setpalette(struct palette *pal, int start, int end, rgb_t * rgb1)
+{
+ driver->set_range((ui_palette) rgb1, start, end);
+}
+
+static void ui_flip(struct image *image)
+{
+ flipgeneric(image);
+ driver->flip_buffers();
+}
+
+static int ui_driverselected(uih_context * c, int d)
+{
+ return (driver == drivers[d]);
+}
+
+static void ui_setdriver(uih_context * c, int d)
+{
+ todriver = d + 1;
+}
+
+static void processbuffer(void)
+{
+ CONST menuitem *item;
+ dialogparam *d;
+ if (uih->incalculation)
+ return;
+ while ((item = menu_delqueue(&d)) != NULL) {
+ ui_menuactivate(item, d);
+ }
+}
+
+static void ui_doquit(int i) NORETURN;
+static void ui_doquit(int i)
+{
+ uih_cycling_off(uih);
+ uih_freecatalog(uih);
+ uih_freecontext(uih);
+ tl_free_timer(maintimer);
+ tl_free_timer(arrowtimer);
+ tl_free_timer(loopt);
+ driver->free_buffers(NULL, NULL);
+ driver->uninit();
+ destroypalette(image->palette);
+ destroy_image(image);
+ xth_uninit();
+ xio_uninit();
+ ui_unregistermenus();
+ uih_unregistermenus();
+ exit_xaos(i);
+}
+
+void ui_quit(void)
+{
+#ifndef _MAC
+ printf(gettext("Thank you for using XaoS\n"));
+#endif
+ ui_doquit(0);
+}
+
+static void ui_quitwr(uih_context * c, int quit)
+{
+ if (c == NULL) {
+ ui_unregistermenus();
+ uih_unregistermenus();
+ xio_uninit();
+ exit_xaos(0);
+ }
+ if (quit)
+ ui_quit();
+}
+
+int ui_key(int key)
+{
+ int sym;
+ char mkey[2];
+ CONST menuitem *item;
+#ifdef _plan9_
+#define ui_keyfilesel(k) 0
+#endif
+ if (!ui_helpkeys(key) && !ui_keyfilesel(key) && !ui_dialogkeys(key)
+ && !ui_menukey(key))
+ switch (sym = tolower(key)) {
+ case ' ':
+ ui_closemenus();
+ uih->display = 1;
+ if (uih->play) {
+ if (uih->incalculation)
+ ui_updatestatus();
+ else {
+ uih_skipframe(uih);
+ driver->print(0, 0,
+ gettext("Skipping, please wait..."));
+ }
+ }
+ break;
+ default:
+ {
+ int number;
+ if (sym >= '0' && sym <= '9') {
+ number = sym - '1';
+ if (number < 0)
+ number = 9;
+ if (number == -1)
+ break;
+ }
+ }
+ mkey[0] = key;
+ mkey[1] = 0;
+ item = menu_findkey(mkey, uih->menuroot);
+ if (item == NULL) {
+ mkey[0] = sym;
+ item = menu_findkey(mkey, uih->menuroot);
+ }
+ if (item != NULL) {
+ dialogparam *p = NULL;
+ if (menu_havedialog(item, uih)) {
+ CONST menudialog *d = menu_getdialog(uih, item);
+ int mousex, mousey, buttons;
+ driver->getmouse(&mousex, &mousey, &buttons);
+ if (d[0].question != NULL && d[1].question == NULL
+ && d[0].type == DIALOG_COORD) {
+ p = (dialogparam *) malloc(sizeof(dialogparam));
+ uih_screentofractalcoord(uih, mousex, mousey,
+ p->dcoord, p->dcoord + 1);
+ }
+ }
+ ui_menuactivate(item, p);
+ }
+ break;
+ }
+ processbuffer();
+ return 0;
+}
+
+#ifdef _EFENCE_
+int EF_ALIGNMENT = 1;
+int EF_PROTECT_BELOW = 0;
+int EF_PROTECT_FREE = 1;
+#endif
+static void ui_helpwr(struct uih_context *c)
+{
+ ui_help("main");
+}
+
+char *ui_getpos(void)
+{
+ return (uih_savepostostr(uih));
+}
+
+void ui_loadstr(CONST char *n)
+{
+ uih_loadstr(uih, n);
+}
+
+static menuitem *menuitems;
+/* This structure is now empty. All static definitions have been moved
+ to ui_registermenus_i18n() which fills up its own static array. */
+
+/* Registering internationalized menus. See also include/xmenu.h
+ for details. Note that MAX_MENUITEMS_I18N may be increased
+ if more items will be added in future. */
+
+/* Details of implementation:
+ *
+ * There are static menuitems_i18n[] arrays for several *.c files.
+ * In these files this array is common for all functions.
+ * Here, e.g. add_resizeitems() and ui_registermenus_i18n()
+ * use the same array and ui_no_menuitems_i18n is the counter
+ * that counts the number of items. The local variables
+ * count the local items.
+ */
+
+#define MAX_MENUITEMS_I18N 20
+/* These variables must be global: */
+static menuitem menuitems_i18n[MAX_MENUITEMS_I18N];
+int ui_no_menuitems_i18n = 0, ui_no_resizeitems;
+static menuitem *resizeitems;
+
+#define UI (MENUFLAG_NOPLAY|MENUFLAG_NOOPTION)
+static void add_resizeitems()
+{
+ // General version, it's needed now:
+ int no_menuitems_i18n = ui_no_menuitems_i18n; /* This variable must be local. */
+ MENUNOP_I("ui", "=", gettext("Resize"), "resize",
+ UI | MENUFLAG_INTERRUPT, ui_call_resize);
+ MENUNOP_I("uia", "=", gettext("Resize"), "animresize",
+ UI | MENUFLAG_INTERRUPT, ui_call_resize);
+ no_menuitems_i18n -= ui_no_menuitems_i18n;
+ resizeitems = &menuitems_i18n[ui_no_menuitems_i18n];
+ menu_add(resizeitems, no_menuitems_i18n);
+ ui_no_resizeitems = no_menuitems_i18n;
+ ui_no_menuitems_i18n += no_menuitems_i18n;
+}
+
+static void ui_registermenus_i18n(void)
+{
+ int no_menuitems_i18n = ui_no_menuitems_i18n; /* This variable must be local. */
+#ifndef MACOSX
+ SUBMENU_I("file", "q", gettext("Quit"), "quitmenu");
+ MENUINT_I("quitmenu", NULL, gettext("Exit now"), "quit",
+ MENUFLAG_INTERRUPT | MENUFLAG_ATSTARTUP, ui_quitwr, 1);
+ MENUINT_I("quitmenu", NULL, gettext("Not yet"), "noquit", UI,
+ ui_quitwr, 0);
+#endif
+ MENUNOP_I("helpmenu", "h", gettext("Help"), "help", MENUFLAG_INCALC,
+ ui_helpwr);
+ MENUNOPCB_I("ui", NULL, gettext("Disable XaoS's builtin GUI"), "nogui",
+ MENUFLAG_INCALC | MENUFLAG_ATSTARTUP | MENUFLAG_NOMENU,
+ ui_noguisw, ui_noguienabled);
+ MENUSEPARATOR_I("ui");
+ MENUNOPCB_I("ui", "/", gettext("Status"), "status", MENUFLAG_INCALC, ui_status, ui_statusenabled); /*FIXME: add also ? as key */
+
+ MENUNOPCB_I("ui", "l", gettext("Ministatus"), "ministatus",
+ MENUFLAG_INCALC, ui_ministatus, ui_ministatusenabled);
+ MENUSEPARATOR_I("ui");
+ MENUSEPARATOR_I("uia");
+ MENUNOPCB_I("uia", "/", gettext("Status"), "animstatus", UI | MENUFLAG_INCALC, ui_status, ui_statusenabled); /*FIXME: add also ? as key */
+
+ MENUNOPCB_I("uia", "l", gettext("Ministatus"), "animministatus",
+ UI | MENUFLAG_INCALC, ui_ministatus, ui_ministatusenabled);
+ MENUSEPARATOR_I("uia");
+ SUBMENU_I("ui", NULL, gettext("Driver"), "drivers");
+ SUBMENU_I("uia", NULL, gettext("Driver"), "drivers");
+ no_menuitems_i18n -= ui_no_menuitems_i18n;
+ menu_add(&(menuitems_i18n[ui_no_menuitems_i18n]), no_menuitems_i18n);
+ ui_no_menuitems_i18n += no_menuitems_i18n;
+}
+
+/* Registering driver items: */
+static menuitem *driveritems;
+static void ui_registermenus(void)
+{
+ int i;
+ menuitem *item;
+ menu_add(menuitems, NITEMS(menuitems));
+ driveritems = item = (menuitem *) malloc(sizeof(menuitem) * ndrivers);
+ for (i = 0; i < ndrivers; i++) {
+ item[i].menuname = "drivers";
+ item[i].shortname = drivers[i]->name;
+ item[i].key = NULL;
+ item[i].type = MENU_INT;
+ item[i].flags = MENUFLAG_RADIO | UI;
+ item[i].iparam = i;
+ item[i].name = drivers[i]->name;
+ item[i].function = (void (*)(void)) ui_setdriver;
+ item[i].control = (int (*)(void)) ui_driverselected;
+ }
+ menu_add(item, ndrivers);
+}
+
+static void ui_unregistermenus(void)
+{
+ menu_delete(menuitems, NITEMS(menuitems));
+ menu_delete(driveritems, ndrivers);
+ menu_delete(menuitems_i18n, ui_no_menuitems_i18n);
+ free(driveritems);
+}
+
+int number_six = 6;
+
+#ifdef SFFE_USING
+ /* parser variables vars */
+cmplx Z, C, pZ;
+#endif
+
+#define MAX_WELCOME 50
+
+void ui_init(int argc, char **argv)
+{
+ int i;
+ int width, height;
+ char welcome[MAX_WELCOME], language[11];
+#ifdef HAVE_GETTEXT
+ char *locale;
+#endif
+#ifdef DESTICKY
+ euid = geteuid();
+ egid = getegid();
+#endif
+#ifdef DESTICKY
+ seteuid(getuid()); /* Don't need supervisor rights anymore. */
+ setegid(getgid());
+#endif
+
+ strcpy(language, "english");
+#ifdef HAVE_GETTEXT
+ /* Setting all locales for XaoS: */
+ locale = setlocale(LC_ALL, "");
+ if (locale == NULL) {
+ printf
+ ("An error occured in your setlocale/gettext installation.\n");
+ printf("I18n menus will not be available.\n");
+ }
+#ifdef _WIN32
+ // x_message("%s",locale);
+ if (locale != NULL) {
+ if (strncmp(locale, "Hungarian", 9) == 0)
+ strcpy(language, "magyar");
+ if (strncmp(locale, "Czech", 5) == 0)
+ strcpy(language, "cesky");
+ if (strncmp(locale, "German", 6) == 0)
+ strcpy(language, "deutsch");
+ if (strncmp(locale, "Spanish", 7) == 0)
+ strcpy(language, "espanhol");
+ if (strncmp(locale, "French", 6) == 0)
+ strcpy(language, "francais");
+ if (strncmp(locale, "Romanian", 8) == 0)
+ strcpy(language, "romanian");
+ if (strncmp(locale, "Italian", 7) == 0)
+ strcpy(language, "italiano");
+ if (strncmp(locale, "Portuguese", 10) == 0)
+ strcpy(language, "portuguese");
+ }
+ // x_message("%s",language);
+#else
+ if ((locale == NULL) || (strcmp(locale, "C") == 0))
+ locale = getenv("LANG");
+ else
+ locale = setlocale(LC_MESSAGES, "");
+
+
+#ifdef DEBUG
+ printf("Trying to use locale settings for %s.\n", locale);
+#endif
+
+ if (locale != NULL) {
+ if (strlen(locale) > 2)
+ locale[2] = '\0';
+ if (strcmp(locale, "hu") == 0)
+ strcpy(language, "magyar");
+ if (strcmp(locale, "cs") == 0)
+ strcpy(language, "cesky");
+ if (strcmp(locale, "de") == 0)
+ strcpy(language, "deutsch");
+ if (strcmp(locale, "es") == 0)
+ strcpy(language, "espanhol");
+ if (strcmp(locale, "fr") == 0)
+ strcpy(language, "francais");
+ if (strcmp(locale, "ro") == 0)
+ strcpy(language, "romanian");
+ if (strcmp(locale, "it") == 0)
+ strcpy(language, "italiano");
+ if (strcmp(locale, "pt") == 0)
+ strcpy(language, "portuguese");
+ }
+#endif
+#ifdef DEBUG
+ printf("Using catalog file for %s language.\n", language);
+#endif
+ /* Without this some locales (e.g. the Hungarian) replaces "." to ","
+ in numerical format and this will cause an automatic truncation
+ at each parameter at certain places, e.g. drawing a new fractal. */
+ setlocale(LC_NUMERIC, "C");
+#ifdef DEBUG
+ printf("Text domain will be bound to directory %s.\n",
+#endif
+ bindtextdomain("xaos",
+#ifdef DOG_DRIVER
+ "..\\locale")
+#ifdef DEBUG
+ )
+#endif
+#else
+#ifdef _WIN32
+ "..\\locale")
+#ifdef DEBUG
+ )
+#endif
+#else
+#ifdef USE_LOCALEPATH
+ localepath)
+#else
+ "/usr/share/locale")
+#endif
+#ifdef DEBUG
+ )
+#endif
+#endif
+#endif
+ ;
+#ifndef _WIN32
+ bind_textdomain_codeset("xaos", "UTF-8");
+#endif
+ textdomain("xaos");
+ /* Done setting locales. */
+#endif
+ xio_init(argv[0]);
+ params_register(global_params);
+ params_register(ui_fractal_params);
+ uih_registermenudialogs_i18n(); /* Internationalized dialogs. */
+ /* Dialogs must be generated before menus because menu items
+ link to dialog pointers. */
+ uih_registermenus_i18n(); /* Internationalized menus. */
+ uih_registermenus();
+ ui_registermenus();
+ ui_registermenus_i18n(); /* Internationalized menus. */
+ for (i = 0; i < ndrivers; i++)
+ params_register(drivers[i]->params);
+#ifdef __alpha__
+#ifdef __linux__
+ extern void ieee_set_fp_control(unsigned long);
+ ieee_set_fp_control(1UL);
+#endif
+#endif
+ prog_argc = argc;
+ prog_argv = argv;
+ if (!params_parser(argc, argv)) {
+ ui_unregistermenus();
+ uih_unregistermenus();
+ xio_uninit();
+ exit_xaos(-1);
+ }
+#ifdef MEM_DEBUG
+ D_NORMAL;
+#endif
+#ifdef DEBUG
+ printf("Initializing driver\n");
+#endif
+#ifndef __BEOS__
+#ifndef _plan9_
+ signal(SIGFPE, SIG_IGN);
+#endif
+#endif
+ if (printconfig) {
+#define tostring(s) #s
+ x_message("XaoS configuration\n"
+ "Version: %s\n"
+ "Type size: %i\n" "integer size: %i\n" "configfile: %s\n"
+#ifndef _plan9_
+#ifdef HAVE_ALLOCA
+ "using alloca\n"
+#endif
+#ifdef HAVE_LONG_DOUBLE
+ "using long double\n"
+#endif
+#ifdef const
+ "const disabled\n"
+#endif
+#ifdef inline
+ "inline disabled\n"
+#endif
+#ifdef HAVE_GETTIMEOFDAY
+ "using gettimeofday\n"
+#endif
+#ifdef HAVE_FTIME
+ "using ftime\n"
+#endif
+#ifdef MITSHM
+ "using mitshm\n"
+#endif
+#ifdef HAVE_MOUSEMASK
+ "using ncurses mouse\n"
+#endif
+#ifdef DEBUG
+ "debug enabled\n"
+#endif
+#ifdef NDEBUG
+ "assertions disabled\n"
+#endif
+#ifdef STATISTICS
+ "statistics enabled\n"
+#endif
+#ifdef SFFE_USING
+ "user formula evaluation\n"
+#endif
+#endif
+ , XaoS_VERSION, (int) sizeof(FPOINT_TYPE),
+ (int) sizeof(int), CONFIGFILE);
+ }
+ if (deflist || printconfig) {
+ char s[256];
+ strcpy(s, "Available drivers: ");
+ for (i = 0; i < ndrivers; i++) {
+ strcat(s, drivers[i]->name);
+ if (i < ndrivers - 1)
+ strcat(s, ", ");
+ }
+ x_message(s);
+ ui_unregistermenus();
+ uih_unregistermenus();
+ xio_uninit();
+ exit_xaos(0);
+ }
+#ifndef _plan9_
+ xth_init(defthreads);
+#endif
+ {
+ int i = ui_dorender_params();
+ if (i) {
+ ui_unregistermenus();
+ uih_unregistermenus();
+ xio_uninit();
+ exit_xaos(i - 1);
+ }
+ }
+ if (defdriver != NULL) {
+ for (i = 0; i < ndrivers; i++) {
+ int y;
+ for (y = 0;
+ tolower(drivers[i]->name[y]) == tolower(defdriver[y])
+ && drivers[i]->name[y] != 0; y++);
+ if (drivers[i]->name[y] == 0) {
+ driver = drivers[i];
+ if (driver->init())
+ break;
+ else {
+ x_fatalerror("Can not initialize %s driver",
+ defdriver);
+ }
+ }
+ }
+ if (i == ndrivers) {
+ x_fatalerror("Unknown driver %s", defdriver);
+ }
+ } else {
+ for (i = 0; i < ndrivers; i++) {
+ driver = drivers[i];
+ if (driver->init())
+ break;
+ }
+ if (i == ndrivers) {
+ x_fatalerror("Can not initialize driver");
+ }
+ }
+#ifdef DEBUG
+ printf("Getting size\n");
+#endif
+ driver->getsize(&width, &height);
+#ifdef _plan9_
+ xth_init(defthreads); /*plan0 requires to initialize tasks after graphics */
+#endif
+ mousetype(WAITMOUSE);
+ driver->print(0, 0, "Initializing. Please wait");
+ driver->print(0, textheight1, "Creating framebuffer");
+ ui_flush();
+ ui_mkimages(width, height);
+
+ driver->print(0, textheight1 * 2, "Initializing fractal engine");
+ ui_flush();
+
+ /* gloabuih initialization moved into uih_mkcontext function : malczak */
+ uih =
+ uih_mkcontext(driver->flags, image, ui_passfunc, ui_message,
+ ui_updatemenus);
+
+ if (driver->gui_driver && driver->gui_driver->setrootmenu)
+ driver->gui_driver->setrootmenu(uih, uih->menuroot);
+ ui_flush();
+#ifdef HOMEDIR
+ if (getenv("HOME") != NULL) {
+ char home[256], *env = getenv("HOME");
+ int maxsize = 255 - (int) strlen(CONFIGFILE) - 1; /*Avoid buffer owerflow */
+ int i;
+ for (i = 0; i < maxsize && env[i]; i++)
+ home[i] = env[i];
+ home[i] = 0;
+ xio_addfname(configfile, home, CONFIGFILE);
+ } else
+#endif
+ xio_addfname(configfile, XIO_EMPTYPATH, CONFIGFILE);
+ ui_flush();
+ srand(time(NULL));
+ uih->fcontext->version++;
+ maintimer = tl_create_timer();
+ arrowtimer = tl_create_timer();
+ loopt = tl_create_timer();
+ driver->print(0, textheight1 * 3, "Loading message catalog");
+ ui_flush();
+ uih_loadcatalog(uih, language);
+ driver->print(0, textheight1 * 4, "Initializing timming system");
+ ui_flush();
+ uih_newimage(uih);
+ tl_update_time();
+ /*tl_process_group (syncgroup, NULL); */
+ tl_reset_timer(maintimer);
+ tl_reset_timer(arrowtimer);
+#ifdef COMPILE_PIPE
+ if (defpipe != NULL) {
+ driver->print(0, textheight1 * 5, "Initializing pipe");
+ ui_flush();
+ ui_pipe_init(defpipe);
+ }
+#else
+ if (defpipe != NULL) {
+ x_fatalerror("Pipe input not supported!");
+ }
+#endif
+ /*uih_constantframetime(uih,1000000/20); */
+ driver->print(0, textheight1 * 6, "Reading configuration file");
+ {
+ xio_file f = xio_ropen(configfile); /*load the configuration file */
+ if (f != XIO_FAILED) {
+ uih_load(uih, f, configfile);
+ if (uih->errstring) {
+ x_error("Configuration file %s load failed", configfile);
+ uih_printmessages(uih);
+ x_error("Hint:try to remove it :)");
+ ui_doquit(1);
+ }
+ }
+ }
+ driver->print(0, textheight1 * 7,
+ "Processing command line parameters");
+ ui_flush();
+ {
+ CONST menuitem *item;
+ dialogparam *d;
+ while ((item = menu_delqueue(&d)) != NULL) {
+ uih_saveundo(uih);
+ menu_activate(item, uih, d);
+ }
+ }
+#ifndef _plan9_
+ sprintf(welcome, gettext("Welcome to XaoS version %s"), XaoS_VERSION);
+ /*TYPE*/ uih_message(uih, welcome);
+#endif
+ uih_updatemenus(uih, driver->name);
+ if (printspeed) {
+ int c = 0;
+ int x, y, b, k;
+ int linesize = uih->image->bytesperpixel * uih->image->height;
+ int size = linesize * uih->image->height;
+ driver->print(0, textheight1 * 8, "Preparing for speedtest");
+ ui_flush();
+ uih->passfunc = NULL;
+ tl_sleep(1000000);
+ for (c = 0; c < 5; c++)
+ driver->display(), ui_flush();
+ driver->processevents(0, &x, &y, &b, &k);
+ driver->print(0, textheight1 * 9, "Measuring dislay speed");
+ ui_flush();
+ tl_sleep(1000000);
+ tl_update_time();
+ tl_reset_timer(maintimer);
+ c = 0;
+ while (tl_lookup_timer(maintimer) < 5000000)
+ driver->display(), ui_flush(), driver->processevents(0, &x, &y,
+ &b, &k),
+ tl_update_time(), c++;
+ x_message("Driver speed: %g FPS (%.4f MBPS)", c / 5.0,
+ c * (double) size / 5.0 / 1024 / 1024);
+
+ driver->print(0, textheight1 * 10, "Measuring memcpy speed");
+ ui_flush();
+ for (c = 0; c < 5; c++) {
+ for (x = 0; x < uih->image->height; x++)
+ memcpy(uih->image->currlines[y], uih->image->oldlines[y],
+ linesize);
+ }
+ tl_update_time();
+ tl_reset_timer(maintimer);
+ c = 0;
+ while (tl_lookup_timer(maintimer) < 5000000) {
+ for (x = 0; x < uih->image->height; x++)
+ memcpy(uih->image->currlines[y], uih->image->oldlines[y],
+ linesize);
+ tl_update_time(), c++;
+ }
+ x_message("Memcpy speed: %g FPS (%.4f MBPS)", c / 5.0,
+ c * (double) size / 5.0 / 1024 / 1024);
+
+ driver->print(0, textheight1 * 10,
+ "Measuring missaligned memcpy speed");
+ tl_update_time();
+ tl_reset_timer(maintimer);
+ c = 0;
+ while (tl_lookup_timer(maintimer) < 5000000) {
+ for (x = 0; x < uih->image->height; x++)
+ memcpy(uih->image->currlines[y] + 1,
+ uih->image->oldlines[y] + 2, linesize - 2);
+ tl_update_time(), c++;
+ }
+ x_message("Missaligned memcpy speed: %g FPS (%.4f MBPS)", c / 5.0,
+ c * (double) size / 5.0 / 1024 / 1024);
+
+ driver->print(0, textheight1 * 10, "Measuring size6 memcpy speed");
+ tl_update_time();
+ tl_reset_timer(maintimer);
+ c = 0;
+ while (tl_lookup_timer(maintimer) < 5000000) {
+ int x, y;
+ for (y = 0; y < uih->image->height; y++)
+ for (x = 0; x < linesize - 6; x += 6) {
+ memcpy(uih->image->currlines[y] + x,
+ uih->image->oldlines[y] + x, number_six);
+ }
+ tl_update_time(), c++;
+ }
+ x_message("Size 6 memcpy speed: %g FPS (%.4f MBPS)", c / 5.0,
+ c * (double) size / 5.0 / 1024 / 1024);
+
+ driver->display();
+ driver->print(0, textheight1 * 11, "Measuring calculation speed");
+ ui_flush();
+ speed_test(uih->fcontext, image);
+ driver->print(0, textheight1 * 12,
+ "Measuring new image calculation loop");
+ ui_flush();
+ uih_prepare_image(uih);
+ tl_update_time();
+ tl_reset_timer(maintimer);
+ for (c = 0; c < 5; c++)
+ uih_newimage(uih), uih->fcontext->version++,
+ uih_prepare_image(uih);
+ driver->display();
+ ui_flush();
+ x_message("New image caluclation took %g seconds (%.2g fps)",
+ tl_lookup_timer(maintimer) / 5.0 / 1000000.0,
+ 5000000.0 / tl_lookup_timer(maintimer));
+ tl_update_time();
+ for (c = 0; c < 5; c++)
+ uih_animate_image(uih), uih_prepare_image(uih), c++;
+ c = 0;
+ tl_update_time();
+ tl_reset_timer(maintimer);
+ driver->print(0, textheight1 * 13,
+ "Measuring zooming algorithm loop");
+ ui_flush();
+ while (tl_lookup_timer(maintimer) < 5000000)
+ uih_animate_image(uih), uih_prepare_image(uih),
+ tl_update_time(), c++;
+ x_message("Approximation loop speed: %g FPS", c / 5.0);
+ ui_doquit(0);
+ }
+#ifdef SFFE_USING
+ /*SFFE : malczak */
+ if (uih->parser->expression == NULL)
+ if (sffeform)
+ err = sffe_parse(&uih->parser, (char *) sffeform);
+ else
+ sffe_parse(&uih->parser, "z^2+c");
+
+ if (sffeinit) {
+ uih->pinit = sffe_alloc();
+ sffe_regvar(&uih->pinit, &pZ, 'p');
+ sffe_regvar(&uih->pinit, &C, 'c');
+ if (sffe_parse(&uih->pinit, (char *) sffeinit) > 0)
+ sffe_free(&uih->pinit);
+ };
+
+ if (err > 0)
+ sffe_parse(&uih->parser, "z^2+c");
+ /*SFFE*/
+#endif
+ driver->print(0, textheight1 * 8, "Entering main loop");
+ ui_flush();
+}
+
+#ifndef MAIN_FUNCTION
+#define MAIN_FUNCTION main
+#endif
+int MAIN_FUNCTION(int argc, char **argv)
+{
+ ui_init(argc, argv);
+ ui_mainloop(1);
+ ui_quit();
+
+ return (0);
+}
+
+static void ui_mkimages(int w, int h)
+{
+ struct palette *palette;
+ int scanline;
+ int width, height;
+ union paletteinfo info;
+ char *b1, *b2;
+ width = w;
+ height = h;
+ if (resizeregistered && !(driver->flags & RESIZE_COMMAND)) {
+ menu_delete(resizeitems, ui_no_resizeitems);
+ resizeregistered = 0;
+ } else {
+ if (!resizeregistered && (driver->flags & RESIZE_COMMAND)) {
+ add_resizeitems();
+ resizeregistered = 1;
+ }
+ }
+ if (!(scanline = driver->alloc_buffers(&b1, &b2))) {
+ driver->uninit();
+ x_error(gettext("Can not allocate buffers"));
+ ui_outofmem();
+ exit_xaos(-1);
+ }
+ info.truec.rmask = driver->rmask;
+ info.truec.gmask = driver->gmask;
+ info.truec.bmask = driver->bmask;
+ palette =
+ createpalette(driver->palettestart, driver->paletteend,
+ driver->imagetype,
+ (driver->
+ flags & RANDOM_PALETTE_SIZE) ? UNKNOWNENTRIES : 0,
+ driver->maxentries,
+ driver->set_color != NULL ? ui_alloccolor : NULL,
+ driver->set_range != NULL ? ui_setpalette : NULL,
+ NULL, NULL, &info);
+ if (!palette) {
+ driver->uninit();
+ x_error(gettext("Can not create palette"));
+ ui_outofmem();
+ exit_xaos(-1);
+ }
+ image =
+ create_image_cont(width, height, scanline, 2, (unsigned char *) b1,
+ (unsigned char *) b2, palette, ui_flip,
+ (driver->flags & AALIB) ? AAIMAGE : 0,
+ get_windowwidth(width) / width,
+ get_windowheight(height) / height);
+ if (!image) {
+ driver->uninit();
+ x_error(gettext("Can not create image"));
+ ui_outofmem();
+ exit_xaos(-1);
+ }
+}
+
+void ui_resize(void)
+{
+ int w, h;
+
+ /* Prevent crash on startup for Mac OS X */
+ if (!uih)
+ return;
+
+ if (uih->incalculation) {
+ uih_interrupt(uih);
+ return;
+ }
+ ui_closemenus();
+ ui_closedialog(0);
+ ui_close_help();
+ uih_clearwindows(uih);
+ uih_stoptimers(uih);
+ uih_cycling_stop(uih);
+ uih_savepalette(uih);
+ driver->getsize(&w, &h);
+ assert(w > 0 && w < 65000 && h > 0 && h < 65000);
+ if (w != uih->image->width || h != uih->image->height
+ || (driver->flags & UPDATE_AFTER_RESIZE)
+ || uih->palette->type != driver->imagetype) {
+ driver->free_buffers(NULL, NULL);
+ destroy_image(uih->image);
+ destroypalette(uih->palette);
+ ui_mkimages(w, h);
+ if (!uih_updateimage(uih, image)) {
+ driver->uninit();
+ x_error(gettext("Can not allocate tables"));
+ ui_outofmem();
+ exit_xaos(-1);
+ }
+ tl_process_group(syncgroup, NULL);
+ tl_reset_timer(maintimer);
+ tl_reset_timer(arrowtimer);
+ uih_newimage(uih);
+ }
+ uih_newimage(uih);
+ uih_restorepalette(uih);
+ /*uih_mkdefaultpalette(uih); */
+ uih->display = 1;;
+ uih_cycling_continue(uih);
+}
+
+static void ui_driver(int d)
+{
+ CONST struct ui_driver *driver1;
+ int width, height;
+ ui_closemenus();
+ ui_closedialog(0);
+ ui_close_help();
+ if (d < 0)
+ d = 0;
+ if (d >= ndrivers)
+ d = ndrivers - 1;
+ uih_stoptimers(uih);
+ driver1 = driver;
+ uih_clearwindows(uih);
+ uih_cycling_off(uih);
+ uih_savepalette(uih);
+ driver->free_buffers(NULL, NULL);
+ driver->uninit();
+ driver = drivers[d];
+ if (!driver->init()) {
+ driver = driver1;
+ uih_error(uih, gettext("Can not initialize driver"));
+ if (!driver1->init()) {
+ x_fatalerror(gettext
+ ("Can not return back to previous driver"));
+ } else
+ driver = driver1;
+ }
+ driver->getsize(&width, &height);
+ destroy_image(uih->image);
+ destroypalette(uih->palette);
+ uih->flags = driver->flags;
+ ui_mkimages(width, height);
+ if (!uih_updateimage(uih, image)) {
+ driver->uninit();
+ x_error(gettext("Can not allocate tables"));
+ ui_outofmem();
+ exit_xaos(-1);
+ }
+ if (driver->gui_driver && driver->gui_driver->setrootmenu)
+ driver->gui_driver->setrootmenu(uih, uih->menuroot);
+ tl_process_group(syncgroup, NULL);
+ tl_reset_timer(maintimer);
+ tl_reset_timer(arrowtimer);
+ uih->display = 1;
+ uih_newimage(uih);
+ uih_restorepalette(uih);
+ ui_updatestatus();
+ uih_updatemenus(uih, driver->name);
+}
+
+static void ui_mainloop(int loop)
+{
+ int inmovement = 1;
+ int x, y, b, k;
+ int time;
+ driver->processevents((!inmovement && !uih->inanimation), &x, &y, &b,
+ &k);
+ do {
+ mousetype(uih->play ? REPLAYMOUSE : uih->
+ inhibittextoutput ? VJMOUSE : NORMALMOUSE);
+ if (uih->display) {
+ uih_prepare_image(uih);
+ ui_updatestatus();
+ }
+ if ((time = tl_process_group(syncgroup, NULL)) != -1) {
+ if (!inmovement && !uih->inanimation) {
+ if (time > 1000000 / 50)
+ time = 1000000 / 50;
+ if (time > delaytime) {
+ tl_sleep(time - delaytime);
+ tl_update_time();
+ }
+ }
+ inmovement = 1;
+ }
+ if (delaytime || maxframerate) {
+ tl_update_time();
+ time = tl_lookup_timer(loopt);
+ tl_reset_timer(loopt);
+ time = 1000000 / maxframerate - time;
+ if (time < delaytime)
+ time = delaytime;
+ if (time) {
+ tl_sleep(time);
+ tl_update_time();
+ }
+ }
+ processbuffer();
+ driver->processevents((!inmovement && !uih->inanimation), &x, &y,
+ &b, &k);
+
+ inmovement = 0;
+ ui_mouse(x, y, b, k);
+ if (todriver)
+ ui_driver(todriver - 1), todriver = 0;
+ if (callresize)
+ ui_resize(), callresize = 0;
+ } while (loop);
+}