#include <tc.h>
#include <pthread.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sched.h>
#include <math.h>
#include <pthread.h>
#include "gr_fractal_complex.h"
#include "gr_fractal.h"
#include "pxx_pipe.ih"
static bool flag = true;
static pthread_t tid;
guchar rgbbuf[PARTS_IN_SIDE][PARTS_IN_SIDE][PART_SIZE * PART_SIZE * 3];
GtkWidget *dareas[PARTS_IN_SIDE][PARTS_IN_SIDE];
pxx::Pipe s_pipe;
gboolean on_darea_expose(GtkWidget *widget,
GdkEventExpose *event,
gpointer user_data) {
gdk_draw_rgb_image (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL],
0, 0, PART_SIZE, PART_SIZE,
GDK_RGB_DITHER_MAX, (guchar*)user_data,
PART_SIZE * 3);
return TRUE;
}
inline void make_color(unsigned iter, guchar &r, guchar &g, guchar &b)
{
#if 1
guchar i = 64;
guchar i1 = iter % i;
guchar i2 = (i-iter) % i;
r = 4*i1;
g = i1*i2/5;
b = 4*i2;
#else
r = 16 * (iter & 15); iter >>= 4;
g = 16 * (iter & 15); iter >>= 4;
b = 16 * (iter & 15); iter >>= 4;
#endif
}
void gtk_draw_part(int _i, int _j, struct part const* _part) {
dmesg("gtk_draw_part()\n");
gint x, y;
guchar *pos = rgbbuf[_i][_j];
for (y = 0; y < PART_SIZE; y++) {
for (x = 0; x < PART_SIZE; x++) {
make_color(_part->iter[x][y], pos[0], pos[1], pos[2]);
pos += 3;
}
}
GtkWidget *widget = dareas[_i][_j];
gdk_threads_enter();
gdk_draw_rgb_image (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL],
0, 0, PART_SIZE, PART_SIZE,
GDK_RGB_DITHER_MAX, rgbbuf[_i][_j],
PART_SIZE * 3);
gdk_threads_leave();
}
void wait_thread ()
{
pthread_join(tid, NULL);
}
gint delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer) {
if (flag) {
finish();
}
gtk_main_quit();
return TRUE;
}
void run_gtk_main ()
{
atexit(wait_thread);
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
char c;
s_pipe.write(&c, 1);
}
void gtk_init_table() {
GtkWidget *window;
GtkWidget *button;
GtkWidget *table;
char name[256];
gethostname(name, sizeof(name));
int argc = 1;
char *myarg = "gr_fractal";
char **argv = &myarg;
g_thread_init(NULL);
gtk_init (&argc, &argv);
gdk_rgb_init();
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Franimation");
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (delete_event), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 20);
table = gtk_table_new (PARTS_IN_SIDE, PARTS_IN_SIDE, TRUE);
gtk_container_add (GTK_CONTAINER (window), table);
int i, j;
for (i = 0; i < PARTS_IN_SIDE; i++) {
for (j = 0; j < PARTS_IN_SIDE; j++) {
GtkWidget *darea;
gint x, y;
guchar *pos;
dareas[i][j] = darea = gtk_drawing_area_new();
gtk_drawing_area_size (GTK_DRAWING_AREA (darea), PART_SIZE, PART_SIZE);
gtk_signal_connect (GTK_OBJECT (darea), "expose-event",
GTK_SIGNAL_FUNC (on_darea_expose), rgbbuf[i][j]);
gtk_table_attach_defaults (GTK_TABLE(table), darea, i, i+1, j, j+1);
gtk_widget_show (darea);
}
}
gtk_widget_show (table);
gtk_widget_show (window);
pthread_create(&tid, NULL, (void* (*)(void*))run_gtk_main, NULL);
}
void gtk_wait() {
char c;
flag = false;
s_pipe.read(&c, 1);
}