[cairo] How to draw Cairo graphic in a Motif drawing widget

George Wu george.wu at navy.mil
Tue May 10 16:54:37 UTC 2016


Hi Lawrence,

Thank you for your answer.

Actually, I did follow the examples shown in Cairo.org, and successfully
drawn graphics on X-Window created using Xlib functions, not using the
Motif widgets.

Here is my code of using Motif widgets to generate an X-Window with a
drawing area, and I want to draw a red dot at the middle of the drawing
area using Cairo functions, and I should see the red dot when the X-Window
pops up. Unfortunately, I got the following error message:

============================================================================

X Error of failed request:  BadDrawable (invalid Pixmap or Window parameter)
  Major opcode of failed request:  53 (X_CreatePixmap)
  Resource id in failed request:  0x0
  Serial number of failed request:  204
  Current serial number in output stream:  213

============================================================================

Here is my C code:

============================================================================

#include <Xm/Xm.h>
#include <Xm/MainW.h>
#include <Xm/CascadeB.h>
#include <Xm/DrawingA.h>
#include <Xm/RowColumn.h>

#include <stdlib.h>
#include <assert.h>
#include <math.h>

#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>

Display *dpy;
Screen *scr;
Window win;
int scrnum;

cairo_surface_t *sfc;
cairo_t *ctx;

unsigned int Width = 500, Height = 500;

void quitCB() {
    cairo_destroy(ctx);
    cairo_surface_destroy(sfc);
    XCloseDisplay(dpy); 
    printf("Quitting program\n");
    exit(0);
}

/* DrawingArea Callback. NOTE: cbk->reason says type of callback event */
void drawCB(Widget w, XtPointer data, XmDrawingAreaCallbackStruct *cbk) {
    if(cbk->reason != XmCR_EXPOSE) { /* Should NEVER HAPPEN for this program */
	printf("X is screwed up!!\n");
	exit(0);
    } 

    cairo_set_line_width(ctx, 20);
    cairo_set_source_rgb(ctx, 1, 0, 0);

    cairo_set_line_cap(ctx, CAIRO_LINE_CAP_ROUND);
    cairo_move_to(ctx, Width / 2.0, Height / 2.0);
    cairo_close_path(ctx);
    cairo_stroke(ctx);

    printf("Get to here.\n");
}

int main(int argc, char *argv[]) {
    Widget top_wid, main_w, menu_bar, draw, quit;
    XtAppContext app;

    top_wid = XtVaAppInitialize(&app, "TopLevel", NULL, 0, &argc, argv,
NULL, XmNwidth, Width, XmNheight, Height, NULL);

    main_w = XtVaCreateManagedWidget("MainWin", xmMainWindowWidgetClass,
top_wid, NULL);
        
    menu_bar = XmCreateMenuBar(main_w, "MenuBar", NULL, 0);        
    XtManageChild(menu_bar);
      
    /* create quit widget + callback */
        
    quit = XtVaCreateManagedWidget("Quit", xmCascadeButtonWidgetClass,
menu_bar, XmNmnemonic, 'Q', NULL);
    XtAddCallback(quit, XmNactivateCallback, quitCB, NULL);

    /* Create a DrawingArea widget. */
    draw = XtVaCreateWidget("draw", xmDrawingAreaWidgetClass, main_w, NULL);
        
    /* Set Cairo surface & context */
    dpy = XtDisplay(draw);
    win = XtWindow(draw);
    scrnum = DefaultScreen(dpy);
 
    sfc = cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy, scrnum),
Width, Height);
    cairo_xlib_surface_set_size(sfc, Width, Height);
    ctx = cairo_create(sfc);

    assert((sfc != NULL) && (ctx != NULL));

    /* set the DrawingArea as the "work area" of main window */
    XtVaSetValues(main_w, XmNmenuBar, menu_bar, XmNworkWindow, draw, NULL);
    XtAddCallback(draw, XmNexposeCallback, drawCB, NULL);

    XtManageChild(draw);

    XtRealizeWidget(top_wid);
    XtAppMainLoop(app);
    return(1);
}

============================================================================



More information about the cairo mailing list