User avatar
ab1jx
Posts: 403
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

retro xwindows programming question

Sat Oct 07, 2017 1:22 pm

I'm working with Motif, I've got a couple things in my window that work OK. Now I want to draw on one, so I call XtWindowOfObject() (and get 0) and pass that window variable to XDrawLine() and get a BadDrawable error at runtime. I tried calling XtWindowOfObject() on a couple different things, and always seem to get 0. I'm not calling it on the root window but when I printf() it (as %X), it's always 0. I know some of these functions return an integer ID and some return a pointer so evidently there's some hidden incompatibility. It doesn't matter whether I use XtWindow() or XtWindowOfObject(), they give 0 and they don't work.

Maybe I left out a header, I've got:

Code: Select all

#include <X11/Xlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/Notebook.h>
#include <Xm/DrawingA.h>
#include <Xm/Label.h>
#include <stdio.h>
#include <stdlib.h>

User avatar
Paeryn
Posts: 1686
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: retro xwindows programming question

Sat Oct 07, 2017 6:05 pm

Are you perhaps trying to get the window of a widget that hasn't yet been realised? Just creating a widget doesn't automatically give it a window. A window id of 0 means there is no window.

Code was taken from an old motif manual - I just added the XtWindowOfObject() calls.

Code: Select all

#include <stdio.h>
#include <Xm/PushB.h>

int main (int argc, char *argv[])
{
    Widget           toplevel, button;
    XtAppContext     app;
    void             button_pushed(Widget, XtPointer, XtPointer);
    XmString         label;
    Arg              args[2];
    Window           window_id;

    XtSetLanguageProc (NULL, NULL, NULL);
    toplevel = XtVaOpenApplication (&app, "Hello", NULL, 0, &argc, argv,
                                    NULL,sessionShellWidgetClass, NULL);
    label = XmStringCreateLocalized ("Push here to say hello");
    XtSetArg(args[0], XmNlabelString, label);
    button = XmCreatePushButton (toplevel, "pushme", args, 1);

    window_id = XtWindowOfObject(button);
    printf("Window ID straight after widget creation: %X\n", window_id);

    XmStringFree (label);
    XtAddCallback (button, XmNactivateCallback, button_pushed, NULL);
    XtManageChild (button);
    XtRealizeWidget (toplevel);

    window_id = XtWindowOfObject(button);
    printf("Window ID after widgets are realised: %X\n", window_id);

    XtAppMainLoop (app);
}

void button_pushed (Widget widget, XtPointer client_data, XtPointer call_data)
{
    printf ("Hello Yourself!\n");
}

Code: Select all

pi@rpi3:~/Programming/Xt $ gcc motif.c -o motif -lXm -lXt -lX11
pi@rpi3:~/Programming/Xt $ ./motif
Window ID straight after widget creation: 0
Window ID after widgets are realised: E00015
Hello Yourself!
She who travels light — forgot something.

User avatar
ab1jx
Posts: 403
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: retro xwindows programming question

Sun Oct 08, 2017 12:22 am

Yes, thank you, I figured you'd know the solution. That was exactly it, I wasn't realizing anything until I was finished putting stuff on the screen. I assume that probably applies to everything: you can't create a child object until the parent is realized. Some stuff wasn't appearing, like I wanted a Notebook, and within it a RowColum, and within that 2 DrawingAreas plus buttons and labels. I was getting the Notebook and I was able to put some labels on it, but I was also setting a lot to be managed as I went. Couldn't get the DrawingArea to appear. Or draw on the notebook. Seems like I read that managing also does a realize. I'm unstuck anyway, got rid of the BadDrawable.

User avatar
Paeryn
Posts: 1686
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: retro xwindows programming question

Sun Oct 08, 2017 2:21 am

It's been a long time since I used Xtoolkit, I may mis-remember a few details...

You can add children to a parent before realising, it's just until a widget is realised it doesn't have a window. Xtoolkit doesn't ask the X server to create windows until the end of XtRealizeWidget() to avoid sending loads of updates whilst it moves and resizes each widget's window.

XtManageChild(child) calls XtRealizeWidget(child) if it's parent is already realised.
She who travels light — forgot something.

User avatar
ab1jx
Posts: 403
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: retro xwindows programming question

Sun Oct 08, 2017 2:50 am

OK, I thought it was like a stroke command in Postscript where whatever you've plotted doesn't show up until you do a stroke, I think on the outermost object. I wish they could have stuck with functions returning something like -1 on error and setting errno. It's as frustrating to troubleshoot as Javascript where everything works until it doesn't and you have to backtrack and figure out the error.

Return to “Graphics programming”

Who is online

Users browsing this forum: No registered users and 1 guest