Descriere
Implementare
Aplicatii
|
|
Lucrarea nr.
1
Prezentare a Laboratorului
A.Descriere
SYS_LIBRARIES = -lXm -lXt -lX11 -lm
CCOPTIONS = -W -Wall
CC = gcc
SRCS = Graph.c egc.c
OBJS = Graph.o egc.o
ComplexProgramTarget(egc)
NormalLibraryObjectRule()
/*======================================================================*/
/* Exemplu de program utilizand modulul Graph */
/*======================================================================*/
#include <stdio.h>
#include "Graph.h"
int
my_main (int argc, char *argv[])
{
printf ("my_main: argc = %d\n", argc);
Circle (50, 50, 40);
return (0); /* va fi apelat o singura data */
}
B. Implementare
/*======================================================================*/
/* Graph.h */
/*======================================================================*/
extern void main (int argc, char *argv[]);
/*
* Returneaza informatii despre dimensiunea spatiului de desenare
*/
extern int GetmaxX (void);
extern int GetmaxY (void);
/*
* Stabileste culoarea curenta de desenare
*/
extern void set_color (char *color);
/*
* Stabileste culoarea curenta de desenare la combinatia (R,G,B)
* (valori intre 0 si 255)
*/
extern void set_RGBcolor (unsigned int R, unsigned int G, unsigned int B);
/*
* Aprinde un pixel in spatiul ecranului avand coordonatele x,y
*/
extern void PutPixel (int x, int y);
/*
* Seteaza punctul de desenare curent la coordonatele ecran x,y
*/
extern void MoveTo (int x, int y);
/*
* Traseaza un segment de dreapta in culoarea curenta intre
* punctele ecran P1(x1,y1) si P2(x2,y2)
*/
extern void Line (int x1, int y1, int x2, int y2);
/*
* Traseaza un segment de dreapta din pozitia curenta pana la
* punctul aflat la distanta relativa dx,dy (in directiile Ox,Oy)
*/
extern void LineRel (int dx, int dy);
/*
* Traseaza un segment de dreapta din pozitia curenta pana la
* punctul P de coordonate ecran P(x,y)
*/
extern void LineTo (int x, int y);
/*
* Traseaza un cerc cu centrul in punctul x,y (coordonate ecran)
* si raza r (pixeli)
*/
extern void Circle (int x, int y, int r);
/*
* Functie de stergere a ferestrei de desenare
*/
extern void ClearViewport (void);
/*======================================================================*/
/* End of Graph.h */
/*======================================================================*/
/*======================================================================*/
/* Graph.c */
/*======================================================================*/
#include <stdio.h>
#include <Xm/Form.h>
#include <Xm/DrawingA.h>
#include <Xm/MwmUtil.h>
#include <X11/cursorfont.h>
#include "Graph.h"
/* Structuri de Date Private -------------------------------------------*/
static int my_argc;
static char **my_argv;
static GC gc;
static Pixmap pixmap;
static Dimension width, height;
static Display *dpy;
static Widget drawing_a = NULL;
static Pixel CurrCol;
static int CurrX;
static int CurrY;
/* Control cursor mouse */
static Window WID;
static Cursor WCursor;
static Cursor NCursor;
/* Prototipuri Private -------------------------------------------------*/
static Widget Create3DArea (Widget Wparent);
static void redraw (void);
static Boolean Work (void);
static void InitCursor (Widget);
static void WorkCursor (void);
static void NormCursor (void);
/* Rutine Publice ------------------------------------------------------*/
void
main (int argc, char *argv[])
{
XtAppContext app;
Widget main_w;
Widget drawing_a;
Widget toplevel;
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Graph", NULL, 0,
&argc, argv, NULL, NULL);
my_argc = argc;
my_argv = argv;
XtVaSetValues ( toplevel,
XmNmwmDecorations, MWM_DECOR_BORDER |
MWM_DECOR_TITLE |
MWM_DECOR_MENU |
MWM_DECOR_MINIMIZE,
XmNmwmFunctions, MWM_FUNC_MOVE |
MWM_FUNC_CLOSE |
MWM_FUNC_MINIMIZE,
NULL);
main_w = XtVaCreateManagedWidget ("main_w",
xmFormWidgetClass, toplevel,
NULL);
drawing_a = Create3DArea (main_w);
XtVaSetValues (drawing_a,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
XtRealizeWidget (toplevel);
WID = XtWindow (drawing_a);
InitCursor (toplevel);
XtAppAddWorkProc (app, (XtWorkProc)Work, NULL);
XtAppMainLoop (app);
} /* main */
/*
* Returneaza informatii despre dimensiunea spatiului de desenare
*/
int
GetmaxX (void)
{
return (width - 1);
} /* GetmaxX */
int
GetmaxY (void)
{
return (height - 1);
} /* GetmaxY */
/*
* Stabileste culoarea curenta de desenare la combinatia (R,G,B)
* (valori intre 0 si 255)
*/
void
set_RGBcolor (unsigned int R, unsigned int G, unsigned int B)
{
char color[32];
sprintf (color, "#%02X%02X%02X", R & 0xFF, G & 0xFF, B & 0xFF);
set_color (color);
} /* set_RGBcolor */
/*
* Stabileste culoarea curenta de desenare
*/
void
set_color (char *color)
{
Colormap cmap = DefaultColormapOfScreen (XtScreen (drawing_a));
XColor col, unused;
if (!XAllocNamedColor (dpy, cmap, color, &col, &unused))
{
char buf[32];
sprintf (buf, "Can't alloc %s", color);
XtWarning (buf);
return;
}
XSetForeground (dpy, gc, CurrCol = col.pixel);
} /* set_color */
/*
* Aprinde un pixel in spatiul ecranului avand coordonatele x,y
*/
void
PutPixel (int x, int y)
{
CurrX = x;
CurrY = y;
XDrawPoint (dpy, WID, gc, x, y);
XDrawPoint (dpy, pixmap, gc, x, y);
} /* PutPixel */
/*
* Seteaza punctul de desenare curent la coordonatele ecran x,y
*/
void
MoveTo (int x, int y)
{
CurrX = x;
CurrY = y;
} /* MoveTo */
/*
* Traseaza un segment de dreapta in culoarea curenta intre
* punctele ecran P1(x1,y1) si P2(x2,y2)
*/
void
Line (int x1, int y1, int x2, int y2)
{
if (x1 == x2 && y1 == y2)
{
PutPixel (x1, y1);
}
else
{
XDrawLine (dpy, WID, gc, x1, y1, x2, y2);
XDrawLine (dpy, pixmap, gc, x1, y1, x2, y2);
CurrX = x2;
CurrY = y2;
}
} /* Line */
/*
* Traseaza un segment de dreapta din pozitia curenta pana la
* punctul aflat la distanta relativa dx,dy (in directiile Ox,Oy)
*/
void
LineRel (int dx, int dy)
{
Line (CurrX, CurrY, CurrX+dx, CurrY+dy);
} /* LineRel */
/*
* Traseaza un segment de dreapta din pozitia curenta pana la
* punctul P de coordonate ecran P(x,y)
*/
void
LineTo (int x, int y)
{
Line (CurrX, CurrY, x, y);
} /* LineTo */
/*
* Traseaza un cerc cu centrul in punctul x,y (coordonate ecran)
* si raza r (pixeli)
*/
void
Circle (int x, int y, int r)
{
#define FULL_ANGLE 23040 /* 360*64 */
register int x_r = x-r;
register int y_r = y-r;
register int d_r = 2 * r;
XDrawArc (dpy, WID, gc, x_r, y_r, d_r, d_r, 0, FULL_ANGLE);
XDrawArc (dpy, pixmap, gc, x_r, y_r, d_r, d_r, 0, FULL_ANGLE);
} /* Circle */
/*
* Functie de stergere a ferestrei de desenare
*/
void
ClearViewport ()
{
/* clear pixmap with white */
/*-------------------------------------------------------------------*/
/* Sterge pixmap-ul cu alb */
/*-------------------------------------------------------------------*/
XSetForeground (dpy, gc,
WhitePixelOfScreen (XtScreen (drawing_a)));
XFillRectangle (dpy, pixmap, gc, 0, 0, width, height);
/*-------------------------------------------------------------------*/
/* Copiaza pixmap-ul in DrawingArea */
/*-------------------------------------------------------------------*/
if (XtIsRealized (drawing_a))
{
XCopyArea (dpy, pixmap, WID, gc, 0, 0, width, height, 0, 0);
}
/*-------------------------------------------------------------------*/
/* Restaureaza culoarea curenta de desenare */
/*-------------------------------------------------------------------*/
XSetForeground (dpy, gc, CurrCol);
} /* ClearViewport */
/* Rutine Private ------------------------------------------------------*/
static Widget
Create3DArea (Widget Wparent)
{
XGCValues gcv;
/*-------------------------------------------------------------------*/
/* Creeaza un Graphics Context pentru desenare */
/*-------------------------------------------------------------------*/
gcv.foreground = WhitePixelOfScreen (XtScreen (Wparent));
gc = XCreateGC (XtDisplay (Wparent),
RootWindowOfScreen (XtScreen (Wparent)), GCForeground,
&gcv);
/*-------------------------------------------------------------------*/
/* Creeaza un widget DrawingArea, de 5x5 inches, fara resize */
/*-------------------------------------------------------------------*/
drawing_a = XtVaCreateManagedWidget ("drawing_a",
xmDrawingAreaWidgetClass, Wparent,
XmNunitType, Xm1000TH_INCHES,
XmNwidth, 5000, /* 5 inches */
XmNheight, 5000, /* 5 inches */
XmNresizePolicy, XmNONE, /* remain this a fixed size */
NULL);
/*-------------------------------------------------------------------*/
/* Pentru redesenare... */
/*-------------------------------------------------------------------*/
XtAddCallback (drawing_a, XmNexposeCallback, (XtCallbackProc)redraw, NULL);
/*-------------------------------------------------------------------*/
/* Des utilizat, variabila globala */
/*-------------------------------------------------------------------*/
dpy = XtDisplay (drawing_a);
/*-------------------------------------------------------------------*/
/* Stabileste masurarea dimensiunilor in pixeli. */
/*-------------------------------------------------------------------*/
XtVaSetValues (drawing_a, XmNunitType, XmPIXELS, NULL);
/*-------------------------------------------------------------------*/
/* Preia dimensiunile ferestrei de desenare */
/*-------------------------------------------------------------------*/
XtVaGetValues (drawing_a, XmNwidth, &width, XmNheight, &height, NULL);
/*-------------------------------------------------------------------*/
/* Creeaza un pixmap de aceleasi dimensiuni (pentru redesenare) */
/*-------------------------------------------------------------------*/
pixmap = XCreatePixmap (dpy,
RootWindowOfScreen (XtScreen (drawing_a)), width, height,
DefaultDepthOfScreen (XtScreen (drawing_a)));
/*-------------------------------------------------------------------*/
/* Deseneaza negru pe alb */
/*-------------------------------------------------------------------*/
set_color ("black");
/*-------------------------------------------------------------------*/
/* Sterge */
/*-------------------------------------------------------------------*/
ClearViewport ();
return (drawing_a);
} /* Create3DArea */
/*
* redraw este apelat atunci cand portiuni sau intreaga zona de desenare
* este expusa.
*/
static void
redraw ()
{
XCopyArea (dpy, pixmap, WID, gc, 0, 0, width, height, 0, 0);
} /* redraw */
static void
InitCursor (Widget w)
{
WCursor = XCreateFontCursor (dpy, XC_watch);
NCursor = XCreateFontCursor (dpy, XC_left_ptr);
} /* InitCursor */
static void
WorkCursor ()
{
XDefineCursor (dpy, WID, WCursor);
} /* WorkCursor */
static void
NormCursor ()
{
XDefineCursor (dpy, WID, NCursor);
} /* NormCursor */
/*
* O WorkProcedure, apelata de serverul X. Apeleaza repetat rutina
* my_main, pana cand aceasta returneaza 0.
*/
static Boolean
Work ()
{
Boolean result = True;
extern int my_main (int argc, char *argv[]);
WorkCursor ();
result = (0 == my_main (my_argc, my_argv));
NormCursor ();
return (result);
} /* Work */
/*======================================================================*/
/* End of Graph.c */
/*======================================================================*/
Download Graph.h,
Graph.c.
C. Aplicatii
1. Scrieti un program pentru desenarea unui dreptunghi, specificat prin
colturile diagonale stanga jos si dreapta sus.
2. Creati un fisier text avand 2*n valori intregi. Scrieti un program care
citeste acest fisier si traseaza o linie poligonala intre perechi de valori succesive, fiecare pereche fiind interpretata ca fiind abscisa x,
respectiv ordonata y ale unui punct din spatiul de desenare.
3. Scrieti un program care afiseaza in mod aleator puncte in spatiul de
desenare si apoi le sterge, utilizand rutine din modulul Graph.
|