
#include <gtk/gtk.h>

DECL_COMMON

/*
 * We need to write down only overloaded methods.
 */
#define TT_GTK_EUNFINISHED 1
 


/* ttobj */
static BREAK(ttobj) {
    if (o) {
	if (o->native) {
	    gtk_object_destroy((GtkObject *)o->native);
	    o->native = (opaque)0;
	}
    }
}


/* ttwidget */
static BUILD(ttwidget) {
    if ((o->native = (opaque)gtk_fixed_new())) {
	gtk_widget_realize((GtkWidget *)o->native);
	return o;
    }
    return NULL;
}
static void DEF(AddTo_ttwidget)(ttwidget o, ttvisible parent) {
    if (parent && !o->parent) {
	/* prepend to list, cannot use FNDEFAULT(ttwidget)->AddTo() */
	if ((o->next = parent->child_first))
	    parent->child_first->prev = (ttvisible)o;
	else
	    parent->child_last = (ttvisible)o;
	parent->child_first = (ttvisible)o;
	o->prev = NULL;
	o->parent = parent;

	gtk_widget_reparent((GtkWidget *)o->native, (GtkWidget *)parent->native);
	
	if (o->vflags & ttvisible_vflags_visible)
	    gtk_widget_show((GtkWidget *)o->native);
    }
}
static void DEF(SetVisible_ttwidget)(ttwidget o, ttbyte on_off) {
    if (!on_off != !(o->vflags & ttvisible_vflags_visible)) {
	o->vflags ^= ttvisible_vflags_visible;
	if (o->parent) {
	    if (on_off)
		gtk_widget_show((GtkWidget *)o->native);
	    else
		gtk_widget_hide((GtkWidget *)o->native);
	}
    }
}
static void DEF(Remove_ttwidget)(ttwidget o) {
    if (o->parent) {
	FNDEFAULT(ttwidget)->Remove(o);
	
	gtk_widget_reparent((GtkWidget *)o->native, (GtkWidget *)0);
    }
}


static ttbyte HWDEF(Sync)(void) {
    return 1;
}
static ttbyte HWDEF(Flush)(void) {
    return 1;
}
static ttbyte HWDEF(TimidFlush)(void) {
    return 1;
}
#if 0 /* not used */
static ttbyte HWDEF(MainLoop)(void) {
    gtk_main();
    return 1;
}
static void HWDEF(ExitMainLoop)(void) {
    gtk_main_quit();
}
#endif
static ttbyte HWDEF(MainLoopOnce)(ttbyte wait) {
    /* FIXME: this is almost surely wrong */
    gtk_main_quit();
    gtk_main();
    return 1;
}
static void HWDEF(DeleteCallback)(ttcallback o) {
}
static void HWDEF(Close)(void) {
}
static int HWDEF(ConnectionFd)(void) {
  return -1;
}
static ttuint HWDEF(GetErrno)(void) {
  return TT_GTK_EUNFINISHED;
}
static ttuint HWDEF(GetErrnoDetail)(void) {
  return 0;
}
static TT_CONST ttbyte *HWDEF(StrError)(ttuint E) {
    switch (E) {
      case TT_GTK_EUNFINISHED:
	return "gtk support is not finished yet :(";
    }
    return "";
}
static TT_CONST ttbyte *HWDEF(StrErrorDetail)(ttuint E, ttuint S) {
    return "";
}


#ifdef THIS_MODULE
ttfns InitModule(tthw *HW)
#else
ttfns _TT_gtk_InitHW(tthw *HW)
#endif
{
    /*
     * (*HW) must be set even if initialization fails,
     * to report error messages.
     */
    *HW = &gtk_TTFNs.HW;
    
    FAIL(TT_GTK_EUNFINISHED, 0); /* it's unfinished... */
    
    return (ttfns)0;
}
