2015-01-02 8 views
5

मैं सीखने की कोशिश करता हूं कि एक्ससीबी लाइब्रेरी में साझा मेमोरी पिक्समैप्स का उपयोग कैसे करें। क्या आप में से किसी के पास इसका अनुभव है और उदाहरण कोड और/या जानकारी साझा करना चाहते हैं? यह बहुत उपयोगी होगा।xcb के साथ shm pixmap का उपयोग कैसे करें?

धन्यवाद

उत्तर

6

कुछ शोध करने के बाद मुझे पता चला कि कैसे XCB में साझा स्मृति पिक्समैप उपयोग करने के लिए।

#include <stdlib.h> 
#include <stdio.h> 

#include <sys/ipc.h> 
#include <sys/shm.h> 

#include <xcb/xcb.h> 
#include <xcb/shm.h> 
#include <xcb/xcb_image.h> 


#define WID 512 
#define HEI 512 



int main(){ 
    xcb_connection_t*  connection; 
    xcb_window_t   window; 
    xcb_screen_t*   screen; 
    xcb_gcontext_t   gcontext; 
    xcb_generic_event_t* event; 

    uint32_t value_mask; 
    uint32_t value_list[2]; 

    //connect to the X server and get screen 

    connection = xcb_connect(NULL, NULL); 
    screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; 

    //create a window 

    value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; 
    value_list[0] = screen->black_pixel; 
    value_list[1] = XCB_EVENT_MASK_EXPOSURE; 

    window = xcb_generate_id(connection); 

    xcb_create_window(
     connection,    
     screen->root_depth, 
     window,  
     screen->root,  
     0, 0,   
     WID, HEI,  
     0,    
     XCB_WINDOW_CLASS_INPUT_OUTPUT, 
     screen->root_visual,  
     value_mask, value_list 
    ); 

    //create a graphic context 

    value_mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; 
    value_list[0] = screen->black_pixel; 
    value_list[1] = 0; 

    gcontext = xcb_generate_id(connection); 
    xcb_create_gc(connection, gcontext, window, value_mask, value_list); 

    //map the window onto the screen 

    xcb_map_window(connection, window); 
    xcb_flush(connection); 


    //Shm test 
    xcb_shm_query_version_reply_t* reply; 
    xcb_shm_segment_info_t   info; 

    reply = xcb_shm_query_version_reply(
     connection, 
     xcb_shm_query_version(connection), 
     NULL 
    ); 

    if(!reply || !reply->shared_pixmaps){ 
     printf("Shm error...\n"); 
     exit(0); 
    } 

    info.shmid = shmget(IPC_PRIVATE, WID*HEI*4, IPC_CREAT | 0777); 
    info.shmaddr = shmat(info.shmid, 0, 0); 

    info.shmseg = xcb_generate_id(connection); 
    xcb_shm_attach(connection, info.shmseg, info.shmid, 0); 
    shmctl(info.shmid, IPC_RMID, 0); 

    uint32_t* data = info.shmaddr; 

    xcb_pixmap_t pix = xcb_generate_id(connection); 
    xcb_shm_create_pixmap(
     connection, 
     pix, 
     window, 
     WID, HEI, 
     screen->root_depth, 
     info.shmseg, 
     0 
    ); 

    int i = 0; 
    while(1){ 
     usleep(10000); 

     data[i] = 0xFFFFFF; 
     i++; 

     xcb_copy_area(
      connection, 
      pix, 
      window, 
      gcontext, 
      0, 0, 0, 0, 
      WID, HEI 
     ); 

     xcb_flush(connection); 
    } 

    xcb_shm_detach(connection, info.shmseg); 
    shmdt(info.shmaddr); 

    xcb_free_pixmap(connection, pix); 

    xcb_destroy_window(connection, window); 
    xcb_disconnect(connection); 

    return 0; 
} 
+1

'shmctl (..., IPC_RMID, ...) के बाद X सर्वर देता', बुलाया जाना चाहिए कुछ गैर Linux सिस्टम पर आप एक संलग्न नहीं कर सकते हैं:

यहाँ मेरी testcode है इसे हटाने के लिए चिह्नित करने के बाद साझा स्मृति खंड। 'xcb_shm_attach' केवल xcb आउटगोइंग संदेश कतार में अनुरोध जोड़ता है, इसलिए एक्स सर्वर शायद तब तक संलग्न नहीं हुआ है जब 'xcb_shm_attach' रिटर्न। मैं सुझाव देता हूं कि 'shmctl' कॉल को क्लीनअप कोड पर ले जाएं। Http://man7.org/linux/man-pages/man2/shmctl.2.html#NOTES – programmerjake

+0

साझा मेमोरी सेगमेंट पर एक्सेस अनुमतियों का ख्याल रखें; यह केवल वर्तमान उपयोगकर्ता तक ही सीमित रखना सर्वोत्तम है: 'shmget (IPC_PRIVATE, WID * HEI * 4, IPC_CREAT | 0600); ' –

संबंधित मुद्दे