Creare una finestra mediante le funzioni del API di XCB
Da Gambas-it.org - Wikipedia.
Il protocollo XCB (X C-language Binding) è stato realizzato con lo scopo di sostituire Xlib presentando rispetto a quest'ultimo ad esempio dimensioni ridotte, un accesso diretto al protocollo, migliorando il threading e la estensibilità.
XCB consente una compatibilità con Xlib che con XCB, anche attraverso l'uso combinato di risorse presenti in entrambe le librerie.
Per poter fruire delle risorse di XCB in Gambas, bisognerà utilizzare la libreria attualmente alla versione: "libxcb.so.1.1.0 ".
Mostriamo di seguito il codice per creare una semplice finestra di colore bianco che presenta al suo interno alcuni disegni di elementi geometrici:
Library "libxcb:1.1.0" Public Struct xcb_screen_t root As Integer default_colormap As Integer white_pixel As Integer black_pixel As Integer current_input_masks As Integer width_in_pixels As Short height_in_pixels As Short width_in_millimeters As Short height_in_millimeters As Short min_installed_maps As Short max_installed_maps As Short root_visual As Integer backing_stores As Byte save_unders As Byte root_depth As Byte allowed_depths_len As Byte End Struct Public Struct xcb_generic_event_t response_type As Byte pad0 As Byte sequence As Short pad[7] As Integer full_sequence As Integer End Struct Private Const XCB_COPY_FROM_PARENT As Byte = 0 Private Enum XCB_CW_BACK_PIXEL = 2, XCB_GC_FOREGROUND = 4, XCB_CW_EVENT_MASK = 2048, XCB_GC_GRAPHICS_EXPOSURES = 65536 Private Enum XCB_WINDOW_CLASS_COPY_FROM_PARENT = 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_WINDOW_CLASS_INPUT_ONLY Private Enum XCB_EVENT_MASK_NO_EVENT = 0, XCB_EVENT_MASK_KEY_PRESS, XCB_EVENT_MASK_BUTTON_PRESS = 4, XCB_EVENT_MASK_EXPOSURE = 32768 Private Enum XCB_KEY_PRESS = 2, XCB_BUTTON_PRESS = 4, XCB_EXPOSE = 12 Private Enum XCB_COORD_MODE_ORIGIN = 0, XCB_COORD_MODE_PREVIOUS ' xcb_connection_t * xcb_connect (const char *display, int *screen) ' Connects to the X server specified by display. Private Extern xcb_connect(display As String, screenPo As Pointer) As Pointer ' const xcb_setup_t * xcb_get_setup (xcb_connection_t *c) ' Accessor for the data returned by the server when the xcb_connection_t was initialized. Private Extern xcb_get_setup(c As Pointer) As Pointer ' xcb_screen_iterator_t xcb_setup_roots_iterator (const xcb_setup_t *R) ' Get the next element of the iterator. Private Extern xcb_setup_roots_iterator(R As Pointer) As Pointer ' uint32_t xcb_generate_id (xcb_connection *c) ' Allocates an XID prior to creating a new X object. Private Extern xcb_generate_id(c As Pointer) As Integer ' xcb_void_cookie_t xcb_create_window (xcb_connection_t *c, uint8_t depth, xcb_window_t wid, xcb_window_t parent, int16_t x, int16_t y, uint16_t width, uint16_t height, uint16_t border_width, ' uint16_t _class, xcb_visualid_t visual, uint32_t value_mask, const uint32_t *value_list) ' Creates a window. Private Extern xcb_create_window(c As Pointer, depth As Byte, wid As Integer, parent As Integer, xs As Short, ys As Short, width As Short, height As Short, border_width As Short, _class As Short, visual As Integer, value_mask As Integer, value_list As Integer[]) As Integer ' xcb_void_cookie_t xcb_map_window (xcb_connection_t *c, xcb_window_t window) ' Makes a window visible. Private Extern xcb_map_window(c As Pointer, wid As Integer) As Integer ' int xcb_flush(xcb_connection_t *c) ' Forces any buffered output to be written to the server. Private Extern xcb_flush(c As Pointer) As Integer ' xcb_void_cookie_t xcb_create_gc (xcb_connection_t *c, xcb_gcontext_t cid, xcb_drawable_t drawable, uint32_t value_mask, const uint32_t *value_list) ' Creates a graphics context. Private Extern xcb_create_gc(c As Pointer, cid As Integer, drawable As Integer, value_mask As Integer, value_list As Integer[]) As Integer ' xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c) ' Returns the next event or error from the server. Private Extern xcb_wait_for_event(c As Pointer) As Xcb_generic_event_t ' xcb_void_cookie_t xcb_poly_point (xcb_connection_t *c, uint8_t coordinate_mode, xcb_drawable_t drawable, xcb_gcontext_t gc, uint32_t points_len, const xcb_point_t *points) ' Draw points. Private Extern xcb_poly_point(c As Pointer, coordinate_mode As Byte, drawable As Integer, gc_I As Integer, points_len As Integer, points As Short[]) As Integer ' xcb_void_cookie_t xcb_poly_line (xcb_connection_t *c, uint8_t coordinate_mode, xcb_drawable_t drawable, xcb_gcontext_t gc, uint32_t points_len, const xcb_point_t *points) ' Draw lines. Private Extern xcb_poly_line(c As Pointer, coordinate_mode As Byte, drawable As Integer, gc_I As Integer, points_len As Integer, points As Short[]) As Integer ' xcb_void_cookie_t xcb_poly_segment (xcb_connection_t *c, xcb_drawable_t drawable, xcb_gcontext_t gc, uint32_t segments_len, const xcb_segment_t *segments) ' Draw lines. Private Extern xcb_poly_segment(c As Pointer, drawable As Integer, gc_I As Integer, segments_len As Integer, segments As Short[]) As Integer ' xcb_void_cookie_t xcb_poly_rectangle (xcb_connection_t *c, uint8_t coordinate_mode, xcb_drawable_t drawable, xcb_gcontext_t gc, uint32_t rectangles_len, const xcb_rectangle_t *rectangles) ' Draw rectangles. Private Extern xcb_poly_rectangle(c As Pointer, drawable As Integer, gc_I As Integer, rectangles_len As Integer, rectangles As Short[]) As Integer ' xcb_void_cookie_t xcb_poly_arc (xcb_connection_t *c, uint8_t coordinate_mode, xcb_drawable_t drawable, xcb_gcontext_t gc, uint32_t arcs_len, const xcb_arc_t *arcs) ' Draw arcs. Private Extern xcb_poly_arc(c As Pointer, drawable As Integer, gc_I As Integer, arcs_len As Integer, arcs As Short[]) As Integer ' xcb_void_cookie_t xcb_poly_fill_rectangle (xcb_connection_t *c, uint8_t coordinate_mode, xcb_drawable_t drawable, xcb_gcontext_t gc, uint32_t rectangles_len, const xcb_rectangle_t *rectangles) ' Fills rectangles. Private Extern xcb_poly_fill_rectangle(c As Pointer, drawable As Integer, gc_I As Integer, rectangles_len As Integer, rectangles As Short[]) As Integer ' xcb_void_cookie_t xcb_poly_fill_arc (xcb_connection_t *c, uint8_t coordinate_mode, xcb_drawable_t drawable, xcb_gcontext_t gc, uint32_t arcs_len, const xcb_arc_t *arcs) ' Fills arcs. Private Extern xcb_poly_fill_arc(c As Pointer, drawable As Integer, gc_I As Integer, arcs_len As Integer, arcs As Short[]) As Integer ' void xcb_disconnect (xcb_connection *c) ' Closes the file descriptor and frees all memory associated with the connection. Private Extern xcb_disconnect(c As Pointer) Public Sub Main() Dim disp, xcb_setup As Pointer Dim screen As New Xcb_screen_t Dim win, primopiano, mask As Integer Dim vv As New Integer[] Dim points, polyline, segments, rectangles, arcs, fillrect, fillarc As Short[] Dim evento As New Xcb_generic_event_t ' Apre una connessione con il server X: disp = xcb_connect(Null, 0) ' Ottiene il primo schermo: xcb_setup = xcb_get_setup(disp) screen = xcb_setup_roots_iterator(xcb_setup) ' Mostra in console alcune informazioni sullo schermo utilizzato: With screen Print "Dimensioni dello schermo:\n" Print "Larghezza in pixel: ", Null, .width_in_pixels Print "Altezza in pixel: ", Null, .height_in_pixels Print "Larghezza in millimetri: "; Null, .width_in_millimeters Print "Altezza in millimetri: ", Null, .height_in_millimeters End With ' Crea un contesto grafico nero per disegnare in primo piano: mask = XCB_GC_FOREGROUND Or XCB_GC_GRAPHICS_EXPOSURES vv = [screen.black_pixel, 0] primopiano = xcb_generate_id(disp) xcb_create_gc(disp, primopiano, screen.root, mask, vv) ' Crea una finestra bianca: win = xcb_generate_id(disp) mask = XCB_CW_BACK_PIXEL Or XCB_CW_EVENT_MASK ' Impone il colore della finestra: vv[0] = screen.white_pixel ' Si impostano i tipi di eventi che dovranno essere visti: vv[1] = XCB_EVENT_MASK_EXPOSURE Or XCB_EVENT_MASK_KEY_PRESS Or XCB_EVENT_MASK_BUTTON_PRESS xcb_create_window(disp, XCB_COPY_FROM_PARENT, win, screen.root, 0, 0, 1000, 800, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen.root_visual, mask, vv) ' Mappa la finestra sullo schermo: xcb_map_window(disp, win) ' Ci si assicura che le istruzioni siano inviate al server X: xcb_flush(disp) ' Vengono definiti i valori per disegnare gli elementi geometrici sulla finestra: points = [50, 50, 50, 100, 100, 50, 100, 100] polyline = [250, 50, 25, 100, 125, -100, 50, 50] segments = [500, 50, 700, 150, 550, 125, 650, 300] rectangles = [50, 250, 200, 100, 400, 250, 50, 200] arcs = [50, 500, 300, 200, 0, 90 * CInt(2 ^ 6), 450, 500, 275, 200, 0, 360 * CInt(2 ^ 6)] fillrect = [100, 450, 140, 30, 20, 300, 100, 100] fillarc = [5, 500, 300, 200, 0, 90 * CInt(2 ^ 6), 450, 500, 275, 200, 0, 270 * CInt(2 ^ 6)] fillarc = [650, 400, 100, 100, 0, 180 * CInt(2 ^ 6), 550, 500, 100, 100, 0, 360 * CInt(2 ^ 6)] Do evento = xcb_wait_for_event(disp) Select evento.response_type Case XCB_EXPOSE ' Disegna gli elementi geometrici: xcb_poly_point(disp, XCB_COORD_MODE_ORIGIN, win, primopiano, 4, points) xcb_poly_line(disp, XCB_COORD_MODE_PREVIOUS, win, primopiano, 4, polyline) xcb_poly_segment(disp, win, primopiano, 2, segments) xcb_poly_rectangle(disp, win, primopiano, 2, rectangles) xcb_poly_arc(disp, win, primopiano, 2, arcs) xcb_poly_fill_rectangle(disp, win, primopiano, 2, fillrect) xcb_poly_fill_arc(disp, win, primopiano, 2, fillarc) xcb_flush(disp) ' Se viene premuto un tasto della tastiera, la finestra si chiude: Case XCB_KEY_PRESS Print "\nPremuto un tasto della tastiera." Break ' Se viene premuto un qualsiasi tasto del mouse stando con il puntatore al di sopra della finestra, questa si chiude: Case XCB_BUTTON_PRESS Print "\nPremuto un tasto del mouse." Break End Select Loop ' Va in chiusura: xcb_disconnect(disp) End