Trying to understand how to show a surface

João Jerónimo joao.jeronimo.89 at gmail.com
Thu Apr 18 18:57:51 PDT 2013


Em 19-04-2013 01:52, darxus at chaosreigns.com escreveu:
> Might be useful to post the code.

Ok. I'll post it then.
I'm linking only the wayland libraries. One also needs to use the 
-std=gnu++11 flag.

#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <wayland-client.h>
#include <wayland-client-protocol.h>
#include <unistd.h>
#include <sys/mman.h>
#include <cstdlib>
#include <cerrno>
#include <fcntl.h>
#include <assert.h>

#define SHM_FILENAME    "/tmp/shm.bufferXXXXXX"
#define SHM_SIZE        10*1024*1024

using namespace std;

struct display_data_s {
     struct wl_compositor *compositor;
     struct wl_shell     *shell;
     struct wl_shm         *shm;
     struct wl_seat         *seat;
     struct wl_output     *output;

     struct wl_shm_pool *shm_pool;
} display_data;

namespace registry_listeners {
     void global(void *data,
                    struct wl_registry *registry,
                    uint32_t id,
                    const char *interface,
                    uint32_t version)
     {
         display_data_s *ddata = (display_data_s*)data;
         printf("Wayland object reported: %-25s     %d;\n", interface, id);

         if (strcmp(interface, "wl_compositor") == 0) {
             ddata->compositor = (struct 
wl_compositor*)wl_registry_bind(registry, id,
                          &wl_compositor_interface, 1);
         } else if (strcmp(interface, "wl_shell") == 0) {
             ddata->shell = (struct wl_shell*)wl_registry_bind(registry, 
id, &wl_shell_interface, 1);
         } else if (strcmp(interface, "wl_seat") == 0) {
             ddata->seat = (struct wl_seat*)wl_registry_bind(registry, id,
                          &wl_seat_interface, 1);
             //wl_seat_add_listener(input->wl_seat, &seat_listener, input);
         } else if (strcmp(interface, "wl_shm") == 0) {
             ddata->shm = (struct wl_shm*)wl_registry_bind(registry, id,
                          &wl_shm_interface, 1);
             //wl_shm_add_listener(client->wl_shm, &shm_listener, client);
         } else if (strcmp(interface, "wl_output") == 0) {
             ddata->output = (struct 
wl_output*)wl_registry_bind(registry, id,
                          &wl_output_interface, 1);
             //wl_output_add_listener(output->wl_output, 
&output_listener, output);
         }
     }

     void global_remove(void *data,
                       struct wl_registry *wl_registry,
                       uint32_t name)
     {
         return;
     }

}

namespace surface_listeners {
     void enter(void *data,
               struct wl_surface *wl_surface,
               struct wl_output *output)
     {
         cout << "surface enters an output" << endl;
     }

     void leave(void *data,
               struct wl_surface *wl_surface,
               struct wl_output *output)
     {
         cout << "surface leaves an output" << endl;

     }
}

int main()
{
     try {
         printf("Hello world!!!!! Example Wayland client...\n");

         // Connect
         struct wl_display *display;
         display = wl_display_connect(NULL);
         if (!display) throw string("Could not connect to display");
         cout << "Connect ok\n" << endl;

         // Registry... Listing objects
         cout << "Listing globals:" << endl;
         struct wl_registry *reg = wl_display_get_registry(display);
         struct wl_registry_listener reg_listener;
         reg_listener.global = registry_listeners::global;
         reg_listener.global_remove = registry_listeners::global_remove;
         wl_registry_add_listener(reg, &reg_listener, 
(void*)&display_data);

         wl_display_dispatch(display);
         wl_display_roundtrip(display);
         cout << "End of globals..." << endl << endl;

         // Create surface
         struct wl_surface *surface = 
wl_compositor_create_surface(display_data.compositor);
         assert(surface);
         struct wl_surface_listener surface_listener;
         surface_listener.enter = surface_listeners::enter;
         surface_listener.leave = surface_listeners::leave;
         wl_surface_add_listener(surface, &surface_listener, NULL);
         //wl_display_dispatch(display);

         // Shell surface... later.....
         //struct wl_shell_surface *shell_surface;
         //shell_surface = 
wl_shell_get_shell_surface(display_data.shell, surface);

         char shm_filename[] = SHM_FILENAME;
         int shmfd = mkostemp(shm_filename, O_CLOEXEC);
         if (shmfd == -1) throw (string("could not create shm buffer 
file... errno is ") + to_string(errno));
         ftruncate(shmfd, SHM_SIZE);
         uint32_t *buffer = (uint32_t*)mmap(NULL, SHM_SIZE, 
PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0);
         if (buffer == MAP_FAILED) throw (string("mmap failed... errno 
is ") + to_string(errno));
         display_data.shm_pool = wl_shm_create_pool(display_data.shm, 
shmfd, SHM_SIZE);
         struct wl_buffer *buffer_wl = (struct 
wl_buffer*)wl_shm_pool_create_buffer(display_data.shm_pool, 0,
                                  100, 200,    // Largura, Altura
                                  100*4 /*stride*/, 
WL_SHM_FORMAT_ARGB8888 /*format*/);
         wl_display_dispatch(display);

         for (int i=0; i<100*200; ++i) {
             buffer[i] = 0x40404040;
         }

         wl_surface_attach(surface, buffer_wl, 0, 0);

         wl_surface_damage(surface, 0, 0, 100, 200);
         wl_surface_commit(surface);

         for(;;);

         // Terminate connection
         wl_display_disconnect(display);

         return 0;
     }
     catch(string &errstr) {
         cout << "FATAL: " << errstr << endl;
     }
}


João Jerónimo





>
> On 04/19, João Jerónimo wrote:
>> Hello.
>>
>> I was trying to understand what is the minimal code needed to get a
>> square painter on the screen. However, although I can make the
>> client talk to the Weston compositor, enumerate the global objects,
>> etc, I can't still see my surface drawn in the compositor scene.
>>
>> The steps that my program makes so far are as follows:
>>   - call wl_display_connect(NULL)
>>   - call wl_display_get_registry(display)
>>   - Install listeners for the registry that wl_registry_bind() many
>> of the advertised objects. However, I'm not listening to the events
>> of the objects advertised by the registry. Is it needed?
>>   - call wl_display_dispatch()  and wl_display_roundtrip()
>>   - call wl_compositor_create_surface()
>>   - mkostemp() a file and ftruncate() it to some 10MB or so
>>   - mmap() the entire file created
>>   - call wl_shm_create_pool()
>>   - call wl_shm_pool_create_buffer()
>>   - call wl_display_dispatch()
>>   - Fill the buffer with some content. I filled it entirely with
>> pattern 0x40404040.
>>   - call wl_surface_attach(surface, buffer, 0, 0)
>>   - Then the program just sits in an infinite loop...
>>
>> Am I missing anything?
>>
>> Sorry for my poor English (assuming that you think it's poor)....
>> João Jerónimo
>>
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20130419/31ac5409/attachment-0001.html>


More information about the wayland-devel mailing list