X-Window (Motif)

Motif

motif.c
//-----------------------------------------------------------------------------
/*
 *      Motif demo, ITU
 *      xnovak99,3BIT,2007/2008,ITU
 */
//-----------------------------------------------------------------------------
#define AUTHOR_NAME "xkalab00"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
 
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <X11/keysym.h>
/*
 * Public include files for widgets used in this file.
 */
#include <Xm/MainW.h>
#include <Xm/Form.h>
#include <Xm/Primitive.h>
#include <Xm/Frame.h>
#include <Xm/DrawingA.h>
#include <Xm/PushB.h>
#include <Xm/Label.h>
#include <Xm/RowColumn.h>
#include <Xm/CascadeB.h>
#include <Xm/MessageB.h>
#include <Xm/PanedW.h>
#include <Xm/Text.h>
#include <Xm/ToggleB.h>
 
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
 
//-----------------------------------------------------------------------------
 
Widget          topLevel, 
                mainWin, 
                frame, 
                menu_bar, 
                messagebox, 
                drawarea,
                pane,
                row, 
                text,
                mainmenub[5], 
                menu, 
                toggle1, 
                toggle2;
 
Pixel           cl_red, cl_black, cl_orange, cl_white, cl_green; //colors
int             used_menu=0;
int             draw_area_usage = 0;
 
static char *lines;
static int nlines;
static int ncols;
 
//-----------------------------------------------------------------------------
// prototypes
 
void AllocColors();
void read_file(const char *name);
extern ssize_t read(int,void *, size_t);
extern int close(int);
 
//-----------------------------------------------------------------------------
//Callbacks
 
void messageboxCB(Widget w, XtPointer client_data, XtPointer call_data)
{
    XtUnmanageChild(messagebox);
}
 
//-----------------------------------------------------------------------------
 
void textCB(Widget w, XtPointer client_data, XtPointer call_data)
{
    //zneplatnime kreslici plochu
    XClearArea(XtDisplay(drawarea),XtWindow(drawarea),0,0,0,0,1);
}
 
//-----------------------------------------------------------------------------
 
void menuCB(Widget w, XtPointer client_data, XtPointer call_data)
{
    //printf("menuCB\n");
    XmString str;
	XmPushButtonCallbackStruct *cb= (XmPushButtonCallbackStruct *)call_data;
   	cb->event->xmotion.x_root=cb->event->xmotion.x_root-cb->event->xmotion.x;
	cb->event->xmotion.y_root=cb->event->xmotion.y_root-cb->event->xmotion.y+25;
    switch((int)client_data)
    {
    case 0://quit button
        exit(1);
    break;
    case 1://first button
        used_menu=0;
        XmMenuPosition(menu,(XButtonPressedEvent *)cb->event);
        XtManageChild(menu);
    break;
    case 2://second button
        used_menu=1;
        XmMenuPosition(menu,(XButtonPressedEvent *)cb->event);
        XtManageChild(menu);
    break;
    case 3://about button
 
        str = XmStringCreateLocalized("About");
        XtVaSetValues(messagebox,XmNdialogTitle,str,
                                    XmNmessageAlignment,XmALIGNMENT_CENTER,NULL);
        XmStringFree(str);
 
        str = XmStringCreateLocalized("ITU demonstracni projekt 2007\n\n" AUTHOR_NAME);
        XtVaSetValues(messagebox,XmNmessageString,str,NULL);
        XmStringFree(str);
 
        str = XmStringCreateLocalized("Leave");
        XtVaSetValues(messagebox,XmNokLabelString,str,NULL);
        XmStringFree(str);
 
        XtManageChild(messagebox);
    break;
 
    default:
    break;
 
    }
}
 
//-----------------------------------------------------------------------------
 
void menu_toggle1CB(Widget w, XtPointer client_data, XtPointer call_data)
{
    unsigned char ro_rw;
    XtVaGetValues(w,XmNset,&ro_rw,NULL);
    if(ro_rw==XmUNSET)
 
        XtVaSetValues(text,XmNeditable,1,NULL);
    else
        XtVaSetValues(text,XmNeditable,0,NULL);
    //printf("toggle1CB:%u\n",ro_rw);
}
 
//-----------------------------------------------------------------------------
 
void menu_toggle2CB(Widget w, XtPointer client_data, XtPointer call_data)
{
    unsigned char progress;
    XtVaGetValues(w,XmNset,&progress,NULL);
    if(progress==XmUNSET) {
        //printf("OFF\n");
        draw_area_usage = 0;
    } else {
        //printf("ON\n");
        draw_area_usage = 1;
    }
    XClearArea(XtDisplay(drawarea),XtWindow(drawarea),0,0,0,0,1);
    //printf("toggle1CB:%u\n",ro_rw);
}
 
//-----------------------------------------------------------------------------
 
void MenuX_ButtonClickCB(Widget w, XtPointer client_data, XtPointer call_data)
{
    //printf("MenuX_buttonclickCB\n");
    if(used_menu==0)
        XtVaSetValues(mainmenub[1],XmNborderColor,client_data,NULL);
    else
        XtVaSetValues(mainmenub[2],XmNborderColor,client_data,NULL);
    //invalidate Drawarea
    XClearArea(XtDisplay(drawarea),XtWindow(drawarea),0,0,0,0,1);
}
 
//-----------------------------------------------------------------------------
 
void da_exposeCB(Widget w, XtPointer client_data, XtPointer call_data)
{
    XmTextPosition textcount = XmTextGetLastPosition(text);
    XmTextPosition textposition = XmTextGetCursorPosition(text);
    Pixel color1;
    Pixel color2;
    //printf("da_exposeCB\n");
    //printf("->%u, %u\n",(int)textposition,(int)textcount);
 
    Arg al[10];
    int ac;
    Dimension width,height;
    ac=0;
    XtSetArg(al[ac],XmNheight,&(height)); ac++;
    XtSetArg(al[ac],XmNwidth,&(width)); ac++;
    XtGetValues(w,al,ac);
    XtVaGetValues(mainmenub[1],XmNborderColor,&color1,NULL);
    XtVaGetValues(mainmenub[2],XmNborderColor,&color2,NULL);
 
    XClearWindow(XtDisplay(w), XtWindow(w));
 
    // drawing primitives
 
    if(draw_area_usage==0)
    {
        XGCValues v;
        GC drawGC;
        v.foreground = color1;
        v.background = color2;
        v.line_width = 1;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w),
			GCForeground | GCLineWidth , &v);
		XDrawLine(XtDisplay(w), XtWindow(w), drawGC, 
							5, 5,
							5, height-5);
		XDrawLine(XtDisplay(w), XtWindow(w), drawGC, 
							5, height-5,
							width-5, height-5);
		XDrawLine(XtDisplay(w), XtWindow(w), drawGC, 
							width-5, height-5,
							width-5, 5);
        XFreeGC(XtDisplay(w),drawGC);
 
        v.foreground = color2;
        v.background = color1;
        v.line_width = 3;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w),
			GCForeground | GCLineWidth , &v);
		XDrawLine(XtDisplay(w), XtWindow(w), drawGC, 
							15, 15,
							15, height-15);
		XDrawLine(XtDisplay(w), XtWindow(w), drawGC, 
							15, height-15,
							width/2, height-15);
        XFreeGC(XtDisplay(w),drawGC);
 
        v.foreground = color1;
        v.background = color2;
        v.line_width = 1;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w),
			GCForeground | GCLineWidth , &v);
		XFillRectangle(XtDisplay(w), XtWindow(w), drawGC, 
							30, 10,
							50, height-50);
        XFreeGC(XtDisplay(w),drawGC);
 
        v.foreground = color2;
        v.background = color1;
        v.line_width = 3;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w),
			GCForeground | GCLineWidth , &v);
		XDrawRectangle(XtDisplay(w), XtWindow(w), drawGC, 
							30, 10,
							50, height-50);
        XFreeGC(XtDisplay(w),drawGC);
 
        v.foreground = color1;
        v.background = color2;
        v.line_style = LineOnOffDash;
        v.line_width = 2;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w),
			GCForeground | GCLineWidth |GCLineStyle , &v);
		XDrawRectangle(XtDisplay(w), XtWindow(w), drawGC, 
							100, 10,
							70, height-50);
		XFillArc(XtDisplay(w), XtWindow(w), drawGC, 
							200, 10,
							70, height-50,90*64,180*64);
 
        XDrawArc(XtDisplay(w), XtWindow(w), drawGC, 
							200, 10,
							70, height-50,270*64,90*64);
 
        XFreeGC(XtDisplay(w),drawGC);
 
        v.foreground = color2;
        v.background = color1;
        v.line_style = LineOnOffDash;
        v.line_width = 2;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w),
			GCForeground | GCLineWidth |GCLineStyle , &v);
		XFillArc(XtDisplay(w), XtWindow(w), drawGC, 
							300, 10,
							70, height-50,0*64,180*64);
		XDrawArc(XtDisplay(w), XtWindow(w), drawGC, 
							300, 10,
							70, height-50,180*64,45*64);
        XFreeGC(XtDisplay(w),drawGC);
 
        v.foreground = cl_black;
        v.background = color1;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w),
			GCForeground | GCBackground , &v);
        XDrawString(XtDisplay(w), XtWindow(w),drawGC,width*3/4,height/2,
                    "ITU demo",8);
        XFreeGC(XtDisplay(w),drawGC);
        v.foreground = color1;
        v.background = color2;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w),
			GCForeground | GCBackground , &v);
        XDrawString(XtDisplay(w), XtWindow(w),drawGC,width*3/4,height*3/4,
                    AUTHOR_NAME,strlen(AUTHOR_NAME));
        char buffer[128]="";
        sprintf(buffer,"position:%u/%u",(unsigned int)textposition,(unsigned int)textcount);
        XDrawString(XtDisplay(w), XtWindow(w),drawGC,width*3/4,height*1/4,
                    buffer,strlen(buffer));
        XFreeGC(XtDisplay(w),drawGC);
 
 
    } else {
	XGCValues v;
        GC drawGC;
        double ratio = ((double) textposition / (double) textcount);
 
        //Pravy obdelnik
        v.foreground = color2;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w), GCForeground, &v);
        XFillRectangle(XtDisplay(w), XtWindow(w), drawGC, 0, 0, width, height);
 
        //Levy obdelnik
        v.foreground = color1;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w), GCForeground, &v);
        XFillRectangle(XtDisplay(w), XtWindow(w), drawGC, 0, 0, ratio * width, height);
 
        //Text
        v.foreground = cl_black;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w), GCForeground, &v);
        char buffer[16]="";
        sprintf(buffer, "%f %%", ratio * 100);
        XDrawString(XtDisplay(w), XtWindow(w), drawGC, width / 2, height / 2, buffer, strlen(buffer));
 
        //Obrys
        v.foreground = cl_black;
        v.line_width = 1;
        drawGC = XCreateGC(XtDisplay(w), XtWindow(w), GCForeground | GCLineWidth , &v);
        XDrawRectangle(XtDisplay(w), XtWindow(w), drawGC, 0, 0, width - 1, height - 1);
 
        XFreeGC(XtDisplay(w),drawGC);
    }
}
 
//-----------------------------------------------------------------------------
 
void da_inputCB(Widget w, XtPointer client_data, XtPointer call_data)
{
    //printf("da_inputCB\n");
}
 
//-----------------------------------------------------------------------------
 
void da_resizeCB(Widget w, XtPointer client_data, XtPointer call_data)
{
    //printf("da_resizeCB\n");
    //da_exposeCB(w,client_data,call_data);
}
 
//-----------------------------------------------------------------------------
 
int main(int argc, char **argv)
{
    XtAppContext app_context;
    Arg al[10];
    int ac=0;
	Widget tmpBtn;
 
    /*
     * Register the default language procedure
     */
    XtSetLanguageProc(NULL, (XtLanguageProc)NULL, NULL);
 
    /*
      application init
    */    
    topLevel = XtVaAppInitialize(
      &app_context,		 	/* Application context */
      "ITU demonstracni aplikace",		/* Application class */
      NULL, 0,				/* command line option list */
      &argc, argv,			/* command line args */
      NULL,				/* for missing app-defaults file */
      NULL);				/* terminate varargs list */
 
    messagebox = XmCreateQuestionDialog(topLevel, "MessageBox", NULL, 0);
    XtUnmanageChild(XmMessageBoxGetChild(messagebox, XmDIALOG_HELP_BUTTON));
    XtUnmanageChild(XmMessageBoxGetChild(messagebox, XmDIALOG_CANCEL_BUTTON));
    XtAddCallback(messagebox, XmNokCallback, messageboxCB, (XtPointer)0);
    XtAddCallback(messagebox, XmNcancelCallback, messageboxCB, (XtPointer)1);
 
    AllocColors(); 
    read_file("motif.c");
 
	mainWin = XtVaCreateManagedWidget(
      "mainWin",			/* widget name */
 
      xmMainWindowWidgetClass,		/* widget class */
      topLevel,				/* parent widget*/
      XmNcommandWindowLocation, XmCOMMAND_BELOW_WORKSPACE,
      NULL);				/* terminate varargs list */
 
    menu_bar = XmCreateMenuBar(mainWin, "main_list", NULL, 0);
	XtVaSetValues(menu_bar,
        XmNheight,30,
		//XmNbottomShadowColor,cl_black,
		//XmNtopShadowColor,cl_red,
		//XmNshadowThickness,0,
		//XmNborderWidth,1,
		XmNspacing,2,
		NULL);
 
    XtManageChild(menu_bar);
 
    mainmenub[0] = XtVaCreateManagedWidget("Quit!",
        xmCascadeButtonWidgetClass, menu_bar,
		XmNborderColor,cl_black,
		XmNborderWidth,1,
		NULL);
    XtAddCallback(mainmenub[0], XmNactivateCallback, menuCB, (void *)0);
 
    mainmenub[1] = XtVaCreateManagedWidget("First color",
        xmCascadeButtonWidgetClass, menu_bar,
		XmNborderColor,cl_orange,
		XmNborderWidth,1,
		XmNmarginWidth,10,
		NULL);
    XtAddCallback(mainmenub[1], XmNactivateCallback, menuCB, (void *)1);
 
    mainmenub[2] = XtVaCreateManagedWidget("Second color",
        xmCascadeButtonWidgetClass, menu_bar,
		XmNborderColor,cl_green,
		XmNborderWidth,1,
		NULL);
    XtAddCallback(mainmenub[2], XmNactivateCallback, menuCB, (void *)2);
 
    mainmenub[3] = XtVaCreateManagedWidget("About",
        xmCascadeButtonWidgetClass, menu_bar,
		XmNborderColor,cl_black,
		XmNborderWidth,1,
		NULL);
    XtAddCallback(mainmenub[3], XmNactivateCallback, menuCB, (void *)3);
 
    //create toggle buttons
 
    toggle1 = XtCreateManagedWidget("Readonly",xmToggleButtonWidgetClass,menu_bar,al,ac);
    XtAddCallback(toggle1, XmNvalueChangedCallback, menu_toggle1CB, NULL);
    toggle2 = XtCreateManagedWidget("Progress",xmToggleButtonWidgetClass,menu_bar,al,ac);
    XtAddCallback(toggle2, XmNvalueChangedCallback, menu_toggle2CB, NULL);
 
 
	//---------------------------------------
	//menu creation
	menu=XmCreatePopupMenu(mainWin,"menu0",al,ac);
	tmpBtn = XtVaCreateManagedWidget(
      	"Orange",				    /* widget name */
      	xmPushButtonWidgetClass,	/* widget class */
      	menu,			            /* parent widget*/
	  	XmNbackground,cl_orange,
      	NULL);				        /* terminate varargs list */
 
    XtAddCallback(tmpBtn, XmNactivateCallback, MenuX_ButtonClickCB, (XtPointer)cl_orange);
	tmpBtn = XtVaCreateManagedWidget(
      	"Black",				     /* widget name */
      	xmPushButtonWidgetClass,   	 /* widget class */
      	menu,			             /* parent widget*/
	  	XmNbackground,cl_black,
	  	XmNforeground,cl_white,
      	NULL);				         /* terminate varargs list */
 
    XtAddCallback(tmpBtn, XmNactivateCallback, MenuX_ButtonClickCB, (XtPointer)cl_black);
	tmpBtn = XtVaCreateManagedWidget(
      	"Red",				     /* widget name */
      	xmPushButtonWidgetClass, /* widget class */
      	menu,			         /* parent widget*/
	  	XmNbackground,cl_red,
      	NULL);				     /* terminate varargs list */
 
    XtAddCallback(tmpBtn, XmNactivateCallback, MenuX_ButtonClickCB, (XtPointer)cl_red);
	tmpBtn = XtVaCreateManagedWidget(
      	"Green",				 /* widget name */
      	xmPushButtonWidgetClass, /* widget class */
      	menu,			         /* parent widget*/
	  	XmNbackground,cl_green,
      	NULL);				     /* terminate varargs list */
    XtAddCallback(tmpBtn, XmNactivateCallback, MenuX_ButtonClickCB, (XtPointer)cl_green);
 
 
    pane = XtVaCreateManagedWidget("pane",
            xmPanedWindowWidgetClass,mainWin,
            NULL);
    /*
        create text editor
    */
    text = XmCreateScrolledText(pane, "scrollText", NULL, 0);
    XtVaSetValues(text,
                        XmNeditMode, XmMULTI_LINE_EDIT,
                        XmNcolumns, ncols,
                        XmNrows, 1,
                        XmNwordWrap, False,
                        XmNmaxLength, 100000000,
                        XmNvalue, lines,
                        //XmNvalue, "lines",
                        XmNheight, 200,
                        XmNwidth, 300,
                        XmNpaneMinimum,200,
                        NULL);
    XtManageChild(text);
 
    /* cursor position callback registration (for text widget)*/
    XtAddCallback(text,XmNmotionVerifyCallback,textCB,NULL);
 
    /*
        DrawArea init
    */
    drawarea = XtVaCreateManagedWidget(
      "drawingArea",			     /* widget name */
      xmDrawingAreaWidgetClass,		   /* widget class */
      pane,				             /* parent widget*/
      XmNwidth, 200,			     /* set startup width */
      XmNheight, 200,			     /* set startup height */
      XmNpaneMinimum,100,
      NULL);				        /* terminate varargs list */
 
    XtAddCallback(drawarea, XmNinputCallback, da_inputCB, NULL);
    XtAddCallback(drawarea, XmNexposeCallback, da_exposeCB, NULL);
    XtAddCallback(drawarea, XmNresizeCallback, da_resizeCB, NULL);
 
    /*
        Place widgets in mainWin
    */
	XmMainWindowSetAreas(mainWin, menu_bar, NULL,NULL  , NULL, NULL);
 
    XtRealizeWidget(topLevel);
    XtAppMainLoop(app_context);
}
 
//-----------------------------------------------------------------------------
 
void AllocColors()
{
	XColor cl;
	Colormap cmap;
	Display *display = XOpenDisplay("");
	cmap = DefaultColormap(display,DefaultScreen(display));
	cl.red = 0x0;cl.green=0x0;cl.blue=0x0;
	if(XAllocColor(display,cmap,&cl)==0)
		fprintf(stderr,"ERR: error allocation color\n");
	cl_black = cl.pixel;
	cl.red = 65535;cl.green=0xc3*0xff;cl.blue=0x00;
	if(XAllocColor(display,cmap,&cl)==0)
		fprintf(stderr,"ERR: error allocation color\n");
	cl_orange = cl.pixel;
	cl.red = 0x00;cl.green=65535;cl.blue=0x00;
	if(XAllocColor(display,cmap,&cl)==0)
		fprintf(stderr,"ERR: error allocation color\n");
	cl_green = cl.pixel;
	cl.red = 65535;cl.green=65535;cl.blue=65535;
	if(XAllocColor(display,cmap,&cl)==0)
		fprintf(stderr,"ERR: error allocation color\n");
	cl_white = cl.pixel;
	cl.red = 65535;cl.green=0x00;cl.blue=0x00;
	if(XAllocColor(display,cmap,&cl)==0)
		fprintf(stderr,"ERR: error allocation color\n");
	cl_red = cl.pixel;
}
 
//-----------------------------------------------------------------------------
 
void read_file(const char *name)
{
        int fd;
        struct stat st;
        char *p,*linep;
 
        if ((fd = open(name, O_RDONLY)) == -1 ||
           fstat(fd, &st) == -1) {
                fprintf(stderr, "Cannot open %s\n", name);
                exit(1);
        }
        lines = XtMalloc(st.st_size+1);
        if (read(fd, lines, st.st_size) != st.st_size) {
                fprintf(stderr, "Cannot read %s\n", name);
                exit(1);
        }
        close(fd);
        p = lines;
        while (p < lines + st.st_size) {
                linep = p;
                if ((p = strchr(p, '\n')) == NULL) break;
                if (p-linep > ncols) ncols = p-linep;
                ++p;
                ++nlines;
        }
        lines[st.st_size] = 0;
}