Drag from a double-buffered openGL window. - Motif

This is a discussion on Drag from a double-buffered openGL window. - Motif ; Hi, Using Red Hat Enterprise Linux WS release 3 (Taroon Update 4) I'm trying to start a drag from a double-buffered OpenGL Motif widget. At the moment I'm not dragging to anywhere or setting up a convert procedure or anything ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: Drag from a double-buffered openGL window.

  1. Drag from a double-buffered openGL window.

    Hi,

    Using Red Hat Enterprise Linux WS release 3 (Taroon Update 4)

    I'm trying to start a drag from a double-buffered OpenGL Motif widget.
    At the moment I'm not dragging to anywhere or setting up a convert
    procedure or anything - I'm simply creating a shell with an openGL
    window and setting up an XmDragContext using XmDragStart when the user
    presses the left button. This starts the drag and sets up the default
    drag icon okay. When I release the button, the icon snaps back and the
    program crashes with the following X error:

    X Error of failed request: BadWindow (invalid Window parameter)
    Major opcode of failed request: 4 (X_DestroyWindow)
    Resource id in failed request: 0xe00015
    Serial number of failed request: 371
    Current serial number in output stream: 377

    When the GLwNdoublebuffer resource of the glwMDrawingAreaWidget is set
    to False it works as expected, so it's something to do with the fact
    that this is a double buffered area. I've also tried this with a
    double and single buffered
    XmDrawingArea and again the single-buffered version worked and the
    double-buffered version didn't.

    My original program, before cutting it down to the following test
    program actual produced a slightly different error. As soon as I
    pressed the button (not when it was released) it crashed with the error

    X Error of failed request: BadMatch (invalid parameter attributes)
    Major opcode of failed request: 1 (X_CreateWindow)
    Serial number of failed request: 227
    Current serial number in output stream: 228

    Creating a core dump of this crash, I could see that it was within the
    call to XmDragStart(canvas, event, args, n); in StartDrag(). Again
    this only happened if the window was double buffered, otherwise
    everything worked fine.

    The following test program can be compiled with under Redhat Enterprise
    4 with:

    cc -g -o test test.c -L/usr/X11R6/lib -lGLw -lGL -lGLU -lXm -lXt -lX11

    Thanks a lot for any help you can give.

    Giles

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include



    Widget top_level = NULL;
    Display *display = NULL;
    XtAppContext app_context;
    GLXContext glXContext;

    #define CANVAS_WIDTH 200
    #define CANVAS_HEIGHT 200


    /************************************************** **************************************\
    StartDrag: Sets up the DragContext. This crashes in the call to
    XmDragStart() or when the drag is released.
    \************************************************* ***************************************/
    static void
    StartDrag(Widget canvas, XEvent *event, String *params, Cardinal
    *num_params)
    {
    Arg args[20];
    Cardinal n;

    printf("StartDrag()\n");

    n = 0;
    XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++;
    XtSetArg(args[n], XmNblendModel, XmBLEND_ALL); n++;
    XmDragStart(canvas, event, args, n);
    } /* End of 'StartGroupDrag()' */


    /************************************************** **************************************\
    Simple draw routine to clear the window to yellow
    \************************************************* ***************************************/
    void
    DrawWindow(Widget widget, XtPointer app_data, XtPointer widget_data)
    {
    GLwDrawingAreaCallbackStruct *cbs
    = (GLwDrawingAreaCallbackStruct *) widget_data;

    glClearColor(1,1,0,1);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
    glXSwapBuffers(display, XtWindow(widget));
    }


    /************************************************** **************************************\
    OpenGL init stuff.
    \************************************************* ***************************************/
    static void
    EditorCanvasInit_CB(Widget widget, XtPointer app_data, XtPointer
    widget_data)
    {
    GLwDrawingAreaCallbackStruct *cbs
    = (GLwDrawingAreaCallbackStruct *) widget_data;
    XVisualInfo *visInfo;

    XtVaGetValues(widget,
    GLwNvisualInfo, &visInfo,
    NULL);

    if (!(glXContext = glXCreateContext(display, visInfo, NULL,
    GL_TRUE)))
    printf("Can't create GLX context.\n");

    glXMakeCurrent(display, XtWindow(widget), glXContext);
    glShadeModel(GL_FLAT);
    glViewport(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, CANVAS_WIDTH, 0, CANVAS_HEIGHT);
    glMatrixMode(GL_MODELVIEW);
    }


    /************************************************** **************************************\
    Main stuff.
    \************************************************* ***************************************/
    int
    main(int argc, char **argv)
    {
    Widget shell, area;
    char transTable[] = {": StartDrag()"};
    XtActionsRec actions[] = {{"StartDrag", StartDrag}};
    XtTranslations translations;


    top_level = XtVaAppInitialize(&app_context, "Test",
    NULL, 0,
    &argc, argv,
    NULL,
    NULL);
    display = XtDisplay(top_level);

    /* XSetErrorHandler(HandleXError); */

    shell = XtVaCreatePopupShell("Shell", applicationShellWidgetClass,
    top_level, NULL);


    /* Set to 0 to make it work. */
    #define MAKE_IT_CRASH 1
    area = XtVaCreateManagedWidget("CanvasArea",
    glwMDrawingAreaWidgetClass,
    shell,
    XmNwidth, CANVAS_WIDTH,
    XmNheight, CANVAS_HEIGHT,
    GLwNrgba, True,
    #if MAKE_IT_CRASH
    GLwNdoublebuffer, True,
    #else
    GLwNdoublebuffer, False,
    #endif
    NULL);

    /* Translations for drag start */
    XtAppAddActions(app_context, actions, XtNumber(actions));
    translations = XtParseTranslationTable(transTable);
    XtOverrideTranslations(area, translations);

    XtAddCallback(area, GLwNginitCallback, EditorCanvasInit_CB,
    (XtPointer) NULL);
    XtAddCallback(area, XmNexposeCallback, DrawWindow, NULL);

    XtRealizeWidget(shell);
    XtPopup(shell, XtGrabNone);
    XtAppMainLoop(app_context);
    }


  2. Re: Drag from a double-buffered openGL window.



    Giles wrote:
    >
    > Hi,
    >
    > Using Red Hat Enterprise Linux WS release 3 (Taroon Update 4)
    >
    > I'm trying to start a drag from a double-buffered OpenGL Motif widget.
    > At the moment I'm not dragging to anywhere or setting up a convert
    > procedure or anything - I'm simply creating a shell with an openGL
    > window and setting up an XmDragContext using XmDragStart when the user
    > presses the left button. This starts the drag and sets up the default
    > drag icon okay. When I release the button, the icon snaps back and the
    > program crashes with the following X error:


    First thing, its not a good idea to use Button1 for Drag-n-Drop. You
    should use Button2.
    Your code below did not include the actions and transTable definitions,
    so it is impossible to guess whether you did it correctly.

    Note that if you use button1, you had better override all translations
    for button1 - that includes down, up, motion, and all combinations
    thereof.

    >
    > X Error of failed request: BadWindow (invalid Window parameter)
    > Major opcode of failed request: 4 (X_DestroyWindow)
    > Resource id in failed request: 0xe00015
    > Serial number of failed request: 371
    > Current serial number in output stream: 377
    >
    > When the GLwNdoublebuffer resource of the glwMDrawingAreaWidget is set
    > to False it works as expected, so it's something to do with the fact
    > that this is a double buffered area. I've also tried this with a
    > double and single buffered
    > XmDrawingArea and again the single-buffered version worked and the
    > double-buffered version didn't.
    >
    > My original program, before cutting it down to the following test
    > program actual produced a slightly different error. As soon as I
    > pressed the button (not when it was released) it crashed with the error
    >
    > X Error of failed request: BadMatch (invalid parameter attributes)
    > Major opcode of failed request: 1 (X_CreateWindow)
    > Serial number of failed request: 227
    > Current serial number in output stream: 228
    >
    > Creating a core dump of this crash, I could see that it was within the
    > call to XmDragStart(canvas, event, args, n); in StartDrag(). Again
    > this only happened if the window was double buffered, otherwise
    > everything worked fine.
    >
    > The following test program can be compiled with under Redhat Enterprise
    > 4 with:
    >
    > cc -g -o test test.c -L/usr/X11R6/lib -lGLw -lGL -lGLU -lXm -lXt -lX11
    >
    > Thanks a lot for any help you can give.
    >
    > Giles
    >
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    >
    > Widget top_level = NULL;
    > Display *display = NULL;
    > XtAppContext app_context;
    > GLXContext glXContext;
    >
    > #define CANVAS_WIDTH 200
    > #define CANVAS_HEIGHT 200
    >
    > /************************************************** **************************************\
    > StartDrag: Sets up the DragContext. This crashes in the call to
    > XmDragStart() or when the drag is released.
    > \************************************************* ***************************************/
    > static void
    > StartDrag(Widget canvas, XEvent *event, String *params, Cardinal
    > *num_params)
    > {
    > Arg args[20];
    > Cardinal n;
    >
    > printf("StartDrag()\n");
    >
    > n = 0;
    > XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++;
    > XtSetArg(args[n], XmNblendModel, XmBLEND_ALL); n++;
    > XmDragStart(canvas, event, args, n);
    > } /* End of 'StartGroupDrag()' */


    You really need a lot more in the StartDrag function. You need to
    specify XmNexportTargets, XmNnumExportTargets, XmNconvertProc, and
    probably XmNclientData.

    >
    > /************************************************** **************************************\
    > Simple draw routine to clear the window to yellow
    > \************************************************* ***************************************/
    > void
    > DrawWindow(Widget widget, XtPointer app_data, XtPointer widget_data)
    > {
    > GLwDrawingAreaCallbackStruct *cbs
    > = (GLwDrawingAreaCallbackStruct *) widget_data;
    >
    > glClearColor(1,1,0,1);
    > glClear(GL_COLOR_BUFFER_BIT);
    > glFlush();
    > glXSwapBuffers(display, XtWindow(widget));
    > }
    >
    > /************************************************** **************************************\
    > OpenGL init stuff.
    > \************************************************* ***************************************/
    > static void
    > EditorCanvasInit_CB(Widget widget, XtPointer app_data, XtPointer
    > widget_data)
    > {
    > GLwDrawingAreaCallbackStruct *cbs
    > = (GLwDrawingAreaCallbackStruct *) widget_data;
    > XVisualInfo *visInfo;
    >
    > XtVaGetValues(widget,
    > GLwNvisualInfo, &visInfo,
    > NULL);
    >
    > if (!(glXContext = glXCreateContext(display, visInfo, NULL,
    > GL_TRUE)))
    > printf("Can't create GLX context.\n");
    >
    > glXMakeCurrent(display, XtWindow(widget), glXContext);
    > glShadeModel(GL_FLAT);
    > glViewport(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
    > glMatrixMode(GL_PROJECTION);
    > glLoadIdentity();
    > gluOrtho2D(0, CANVAS_WIDTH, 0, CANVAS_HEIGHT);
    > glMatrixMode(GL_MODELVIEW);
    > }
    >
    > /************************************************** **************************************\
    > Main stuff.
    > \************************************************* ***************************************/
    > int
    > main(int argc, char **argv)
    > {
    > Widget shell, area;
    > char transTable[] = {": StartDrag()"};
    > XtActionsRec actions[] = {{"StartDrag", StartDrag}};
    > XtTranslations translations;
    >
    > top_level = XtVaAppInitialize(&app_context, "Test",
    > NULL, 0,
    > &argc, argv,
    > NULL,
    > NULL);
    > display = XtDisplay(top_level);
    >
    > /* XSetErrorHandler(HandleXError); */
    >
    > shell = XtVaCreatePopupShell("Shell", applicationShellWidgetClass,
    > top_level, NULL);
    >
    > /* Set to 0 to make it work. */
    > #define MAKE_IT_CRASH 1
    > area = XtVaCreateManagedWidget("CanvasArea",
    > glwMDrawingAreaWidgetClass,
    > shell,
    > XmNwidth, CANVAS_WIDTH,
    > XmNheight, CANVAS_HEIGHT,
    > GLwNrgba, True,
    > #if MAKE_IT_CRASH
    > GLwNdoublebuffer, True,
    > #else
    > GLwNdoublebuffer, False,
    > #endif
    > NULL);
    >
    > /* Translations for drag start */
    > XtAppAddActions(app_context, actions, XtNumber(actions));
    > translations = XtParseTranslationTable(transTable);
    > XtOverrideTranslations(area, translations);
    >
    > XtAddCallback(area, GLwNginitCallback, EditorCanvasInit_CB,
    > (XtPointer) NULL);
    > XtAddCallback(area, XmNexposeCallback, DrawWindow, NULL);
    >
    > XtRealizeWidget(shell);
    > XtPopup(shell, XtGrabNone);
    > XtAppMainLoop(app_context);
    > }


    Show us the transtable and actions variables. And use Button2, not
    Button1.

    --
    Fred L. Kleinschmidt
    Boeing Associate Technical Fellow
    Technical Architect, Common User Interface Services
    M/S 2R-94 (206)544-5225

+ Reply to Thread