1. Need help with creating a GUI window on Linux using libxcb.so XCB API

I'm trying to use the XCB API to create a Window on Peppermint Linux(based on Ubuntu 13.04) and not really sure how to do it. Many of us could learn quite a bit from seeing this program wrote in Euphoria if someone wants to show us how it's done?

libxcb.so is a C library for accessing the XCB API. To open up libxcb.so we must use

include std/dll.e 
atom libxcb 
libxcb = open_dll("libxcb.so") -- Must have a 32bit .so installed if on a 64bit machine. 
if libxcb = 0 then -- libxcb will be 0 if the library cannot be opened. 
   puts(1, "Could not open libxcb.so!\n) 
end if 

Core API of XCB library

Here is a small C program to create a window of size 150x150 pixels, positioned at the top-left corner of the screen. Source code located at XCB Tutorial :

    #include <unistd.h>      /* pause() */ 
 
    #include <xcb/xcb.h> 
 
    int 
    main () 
    { 
        /* Open the connection to the X server */ 
        xcb_connection_t *connection = xcb_connect (NULL, NULL); 
 
 
        /* Get the first screen */ 
        const xcb_setup_t      *setup  = xcb_get_setup (connection); 
        xcb_screen_iterator_t   iter   = xcb_setup_roots_iterator (setup); 
        xcb_screen_t           *screen = iter.data; 
 
 
        /* Create the window */ 
        xcb_window_t window = xcb_generate_id (connection); 
        xcb_create_window (connection,                    /* Connection          */ 
                           XCB_COPY_FROM_PARENT,          /* depth (same as root)*/ 
                           window,                        /* window Id           */ 
                           screen->root,                  /* parent window       */ 
                           0, 0,                          /* x, y                */ 
                           150, 150,                      /* width, height       */ 
                           10,                            /* border_width        */ 
                           XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */ 
                           screen->root_visual,           /* visual              */ 
                           0, NULL );                     /* masks, not used yet */ 
 
 
        /* Map the window on the screen */ 
        xcb_map_window (connection, window); 
 
 
        /* Make sure commands are sent before we pause so that the window gets shown */ 
        xcb_flush (connection); 
 
 
        pause ();    /* hold client until Ctrl-C */ 
 
        xcb_disconnect (connection); 
 
        return 0; 
    } 
 
new topic     » topic index » view message » categorize

2. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API

system_X said...

I'm trying to use the XCB API to create a Window on Peppermint Linux(based on Ubuntu 13.04) and not really sure how to do it. Many of us could learn quite a bit from seeing this program wrote in Euphoria if someone wants to show us how it's done?

Here is a small C program to create a window of size 150x150 pixels, positioned at the top-left corner of the screen. Source code located at XCB Tutorial :

Here's my (untested) port to Eu:

include std/dll.e 
atom libxcb 
libxcb = open_dll("libxcb.so") -- Must have a 32bit .so installed if on a 64bit machine. 
if libxcb = 0 then -- libxcb will be 0 if the library cannot be opened. 
   puts(1, "Could not open libxcb.so!\n) 
end if 
 
constant xcb_connect_ = define_c_func(libxcb, "xcb_connect", {C_POINTER, C_POINTER}, C_POINTER), 
xcb_get_setup_ = define_c_func(libxcb, "xcb_get_setup", {C_POINTER}, C_POINTER), 
-- C wrapper code 
--xcb_setup_roots_iterator_ = define_c_func(open_dll("libxcbeuwrapper.so"), "eu_xcb_setup_roots_iterator", {C_POINTER}, C_POINTER), 
-- no C wrapper code 
xcb_setup_roots_iterator_ = define_c_func(libxcb, "xcb_setup_roots_iterator", {C_POINTER}, C_POINTER), 
xcb_generate_id_ = define_c_func(libxcb, "xcb_generate_id", {C_POINTER}, C_UINT), 
xcb_create_window_ = define_c_proc(libxcb, "xcb_create_window", {C_POINTER, C_INT, C_UINT, C_UINT, C_INT, C_INT, C_INT, C_INT, C_INT, C_INT, C_UINT, C_INT, C_POINTER}), 
xcb_map_window_ = define_c_proc(libxcb, "xcb_map_window", {C_POINTER,C_UINT}), 
xcb_flush_ = define_c_proc(libxcb, "xcb_flush", {C_POINTER}), 
xcb_disconnect_ = define_c_proc(libxcb, "xcb_disconnect", {C_POINTER}), 
XCB_COPY_FROM_PARENT = 0, 
XCB_WINDOW_CLASS_INPUT_OUTPUT = 1 
 
public function xcb_connect(atom a1, atom a2) 
	return c_func(xcb_connect, {a1, a2}) 
end function 
 
public function xcb_get_setup(atom connection) 
	return c_func(xcb_get_setup_, {connection}) 
end function 
 
public function xcb_generate_id(atom connection) 
	return c_func(xcb_generate_id_, {connection}) 
end function 
 
public procedure xcb_create_window(atom connection, integer copy, atom window, 
	atom parentwindow, integer x, integer y, integer w, integer h, 
	integer border, integer class, atom visual, integer flags, atom notused) 
 
	c_proc(xcb_create_window_, {connection, copy, window, parentwindow, 
		x, y, w, h, border, class, visual, flags, notused}) 
end procedure 
 
public procedure xcb_map_window(atom connection, atom window) 
	c_proc(xcb_map_window_, {connection, window} 
end procedure 
 
public procedure xcb_flush(atom connection) 
	c_proc(xcb_flush_, {connection} 
end procedure 
 
public procedure xcb_disconnect(atom connection) 
	c_proc(xcb_disconnect_, {connection} 
end procedure 
 
procedure main() 
        -- Open the connection to the X server 
        atom connection = xcb_connect (0, 0) 
 
 
        -- Get the first screen 
        atom setup  = xcb_get_setup (connection) 
 
	-- this returns a raw struct, so there is no way to convert this to 
	-- euphoria without a C wrapper 
        --xcb_screen_iterator_t   iter   = xcb_setup_roots_iterator (setup); 
 
	-- C wrapper code 
        -- atom iter = xcb_setup_roots_iterator (setup) 
        -- atom screen = peek4u(iter, 0) -- data 
 
	-- no C wrapper code - take advantage of the fact that the only 
	-- element of the struct we really need is the first one 
        atom screen = xcb_setup_roots_iterator (setup) 
 
 
        -- Create the window 
        atom window = xcb_generate_id (connection) 
        xcb_create_window (connection,                    -- Connection          
                           XCB_COPY_FROM_PARENT,          -- depth(same as root) 
                           window,                        -- window Id           
                           peek4u(screen, 0), -- root     -- parent window       
                           0, 0,                          -- x, y                
                           150, 150,                      -- width, height       
                           10,                            -- border_width        
                           XCB_WINDOW_CLASS_INPUT_OUTPUT, -- class               
                           peek4u(screen, 8),--root_visual-- visual              
                           0, 0 )                     -- masks, not used yet 
 
 
        -- Map the window on the screen 
        xcb_map_window (connection, window) 
 
 
        -- Make sure commands are sent before we pause so that the window gets shown 
        xcb_flush (connection) 
 
 
        wait_key() -- pause ()    -- hold client until Ctrl-C 
 
        xcb_disconnect (connection) 
 
end procedure 
 
main() 
 

Here's a C wrapper, if you want/need to use that version of the code instead:

/* C wrapper for dealing with C functions that return structs */ 
#include <xcb/xcb.h> 
xcb_screen_iterator_t * eu_xcb_setup_roots_iterator(const xcb_setup_t * setup) 
{ 
	xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); 
	return &iter; 
} 
new topic     » goto parent     » topic index » view message » categorize

3. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API

jimcbrown said...

Here's a C wrapper, if you want/need to use that version of the code instead:

/* C wrapper for dealing with C functions that return structs */ 
#include <xcb/xcb.h> 
xcb_screen_iterator_t * eu_xcb_setup_roots_iterator(const xcb_setup_t * setup) 
{ 
	xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); 
	return &iter; 
} 

Side note: I know Matt's been working on struct support for 4.1. Any chance that could make its way to returning structs-by-value via c_func/c_proc? This would help with a few other libraries as well.

-Greg

new topic     » goto parent     » topic index » view message » categorize

4. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API

ghaberek said...

Side note: I know Matt's been working on struct support for 4.1. Any chance that could make its way to returning structs-by-value via c_func/c_proc? This would help with a few other libraries as well.

We'd have to understand how compilers handle this. I've never looked to see what they do in those cases, but I agree that it would be extremely useful.

Matt

new topic     » goto parent     » topic index » view message » categorize

5. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API

mattlewis said...
ghaberek said...

Side note: I know Matt's been working on struct support for 4.1. Any chance that could make its way to returning structs-by-value via c_func/c_proc? This would help with a few other libraries as well.

We'd have to understand how compilers handle this. I've never looked to see what they do in those cases, but I agree that it would be extremely useful.

Matt

My understanding was that structs, when returned (passed by value) from a C function, will be passed on the stack. So, a struct made up of 5 elements, each being a 32bit int, will take up 20 bytes of stack space. Likewise, a struct made up of a single element, an array of bytes, with the array having a length of 12, will take up 3 dwords of stack space.

I was thinking that, in these cases, we could somehow encode the length of the struct in the return type, and return a sequence of bytes to be reconstructed by the caller.

new topic     » goto parent     » topic index » view message » categorize

6. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API

jimcbrown said...
mattlewis said...
ghaberek said...

Side note: I know Matt's been working on struct support for 4.1. Any chance that could make its way to returning structs-by-value via c_func/c_proc? This would help with a few other libraries as well.

We'd have to understand how compilers handle this. I've never looked to see what they do in those cases, but I agree that it would be extremely useful.

Matt

My understanding was that structs, when returned (passed by value) from a C function, will be passed on the stack. So, a struct made up of 5 elements, each being a 32bit int, will take up 20 bytes of stack space. Likewise, a struct made up of a single element, an array of bytes, with the array having a length of 12, will take up 3 dwords of stack space.

I was thinking that, in these cases, we could somehow encode the length of the struct in the return type, and return a sequence of bytes to be reconstructed by the caller.

We'd have to figure out how to get that stuff off the stack. Yuck. And I suspect it will work differently on different architectures. Double yuck. Especially considering the semi-hardcoded way we call stuff on x86-64 (and ARM? I can't recall of the top of my head).

I would rather return a sequence containing the data as it would appear if you peeked it as a memstruct.

Matt

new topic     » goto parent     » topic index » view message » categorize

7. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API


Forked into: Returning structs in c_func

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu