1. Need help with creating a GUI window on Linux using libxcb.so XCB API
- Posted by system_X Jul 02, 2013
- 1625 views
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
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; }
2. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API
- Posted by jimcbrown (admin) Jul 02, 2013
- 1588 views
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; }
3. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API
- Posted by ghaberek (admin) Jul 02, 2013
- 1476 views
- Last edited Jul 03, 2013
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
4. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API
- Posted by mattlewis (admin) Jul 03, 2013
- 1435 views
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
5. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API
- Posted by jimcbrown (admin) Jul 03, 2013
- 1440 views
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.
6. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API
- Posted by mattlewis (admin) Jul 03, 2013
- 1488 views
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
7. Re: Need help with creating a GUI window on Linux using libxcb.so XCB API
- Posted by ghaberek (admin) Jul 03, 2013
- 1447 views
Forked into: Returning structs in c_func