/**************************************************************** Uebungen zur Vorlesung "Graphische Datenverarbeitung" Sommersemester 1996 Programm: drawtest2.c Autor: Christian Boehm Programm zeichnet fraktale Schneeflocke. Hier wird eine Pixmap als Puffer verwendet. Bei einem Expose-Event wird nur Pixmap-Inhalt in die Drawing Area kopiert. Bei Resize Neuaufbau der Pixmap. ****************************************************************/ # include # include # include # include Widget DrawAr; /* Drawing Area */ GC fensterGC, pixmapGC; /* Graphik-Kontext fuer XDrawLine...*/ Display* display; Pixmap GraphikPixmap = 0; double SQ36 = 0.288675134; /* sqrt (3.0)/6.0 */ double absw (double a) {return a < 0 ? -a : a ; } void RecursiveDraw (double x1, double y1, double x2, double y2, Drawable w, GC g) { if (absw(x1-x2)<1.0 && absw (y1-y2)<1.0) XDrawLine (display, w, g, (Dimension) x1, (Dimension) y1, (Dimension) x2, (Dimension) y2) ; else { RecursiveDraw (x1, y1, (2*x1+x2)/3, (2*y1+y2)/3, w, g); RecursiveDraw ((2*x1+x2)/3, (2*y1+y2)/3, (x1+x2)/2-SQ36*(y2-y1), (y1+y2)/2+SQ36*(x2-x1), w, g); RecursiveDraw ((x1+x2)/2-SQ36*(y2-y1), (y1+y2)/2+SQ36*(x2-x1), (x1+2*x2)/3, (y1+2*y2)/3, w, g); RecursiveDraw ((x1+2*x2)/3, (y1+2*y2)/3, x2, y2, w, g); } } void resizeCB (Widget widget, XtPointer dum2, XtPointer dum3) { Dimension w, h ; double w1, h1 ; XGCValues werte; /* Struktur zum Setzen von GC-Attributen */ XtVaGetValues (widget, XmNheight, &h, XmNwidth, &w, NULL) ; if (GraphikPixmap) { XFreeGC (display, pixmapGC) ; XFreePixmap (display, GraphikPixmap) ; } GraphikPixmap = XCreatePixmap (display, XtWindow (widget), w, h, 1) ; werte.foreground = 0 ; werte.background = 1 ; pixmapGC = XCreateGC (display, GraphikPixmap, GCForeground | GCBackground, &werte) ; XFillRectangle (display, GraphikPixmap, pixmapGC, 0, 0, w, h) ; werte.foreground = 1 ; werte.background = 0 ; XChangeGC (display, pixmapGC, GCForeground | GCBackground, &werte) ; w1 = (double) w ; h1 = (double) h ; if (w1*1.154700538>h1) w1=h1/4/SQ36 ; else h1=w1*4*SQ36 ; RecursiveDraw (0.0, 0.75*h1, w1, 0.75*h1, GraphikPixmap, pixmapGC) ; RecursiveDraw (w1, 0.75*h1, 0.5*w1, 0.0, GraphikPixmap, pixmapGC) ; RecursiveDraw (0.5*w1, 0.0, 0.0, 0.75*h1, GraphikPixmap, pixmapGC) ; XClearArea (display, XtWindow (DrawAr), 0, 0, w, h, True) ; } void exposeCB (Widget widget, XtPointer clientDaten, XtPointer aufrufDaten) { XmDrawingAreaCallbackStruct* DAinfos; /* Callback-Informationen mit Event-Struktur */ DAinfos = (XmDrawingAreaCallbackStruct*)aufrufDaten; if (! GraphikPixmap) resizeCB (widget, (XtPointer) 0, (XtPointer) 0) ; /* Im Expose-Event angegebenen Fenster-Ausschnitt * von Graphik-Bitmap ins Graphik-Fenster kopieren */ XCopyPlane (display, GraphikPixmap, XtWindow(widget), fensterGC, DAinfos->event->xexpose.x, DAinfos->event->xexpose.y, DAinfos->event->xexpose.width, DAinfos->event->xexpose.height, DAinfos->event->xexpose.x, DAinfos->event->xexpose.y, 1); } void exitCB (Widget dum1, XtPointer dum2, XtPointer dum3) { exit (0) ; } static char * fallbackRessourcen [] = { "Drawtest.geometry: 200x200+0+0", NULL } ; main (int argc, char ** argv) { XtAppContext kontext; /* Applikations-Umgebung */ Widget applShell; /* Applikations-Shell */ Widget ExBt; XGCValues werte; /* Struktur zum Setzen von GC-Attributen */ applShell = XtAppInitialize (&kontext, "Drawtest", (XrmOptionDescRec*)NULL, 0, &argc, argv, fallbackRessourcen, (Arg*)NULL, 0); DrawAr = XtCreateManagedWidget ("drawingarea", xmDrawingAreaWidgetClass, applShell, (Arg*)NULL, 0) ; ExBt = XtCreateManagedWidget ("exit", xmPushButtonWidgetClass, DrawAr, (Arg*)NULL, 0) ; XtRealizeWidget (applShell); display = XtDisplay (applShell); /* Fuer die Graphik-Ausgabe wird ein Graphik-Kontext (GC) erzeugt und mit den Vorder- und Hintergrundfarben der Drawing-Area-Widget besetzt. */ XtVaGetValues (DrawAr, XmNforeground, &(werte.foreground), XmNbackground, &(werte.background), NULL) ; fensterGC = XCreateGC (display, XtWindow (DrawAr), GCForeground | GCBackground, &werte) ; /* Callbacks registrieren. Der Resize-Callback darf erst nach XtRealizeWidget registriert werden */ XtAddCallback (DrawAr, XmNexposeCallback, exposeCB, (XtPointer)NULL); XtAddCallback (DrawAr, XmNresizeCallback, resizeCB, (XtPointer)NULL); XtAddCallback (ExBt, XmNactivateCallback, exitCB, (XtPointer) NULL); XtAppMainLoop (kontext); }