Compare commits

...

110 Commits

Author SHA1 Message Date
Enrico Weigelt, metux IT consult 0843fc86ac Revert "ci: build on xcbproto/libxcb master"
This reverts commit 026815ebac5f3117def7156f375cdbe31c657585.
2024-08-26 14:39:19 +02:00
Enrico Weigelt, metux IT consult 3a26b575b5 Revert "(nomerge): ci: build xcb from our own branch"
This reverts commit 9ba28665b8fe418bccb0c1669b03149f7a1fbe2a.
2024-08-26 14:39:19 +02:00
Enrico Weigelt, metux IT consult 6dcb6bb77c (nomerge): ci: build xcb from our own branch
Temporary workaround, until XCB fix is merged.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 66d7dbed01 ci: build on xcbproto/libxcb master
Make newer version and yet unreleased fixes available to our build.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 3455cdcd3f Xnest: dont link Xlib anymore
Now that we completely ported from Xlib to XCB, we can finally stop
importing Xlib :)

FIN.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 6e4914ffd0 Xnest: use XCB for upstream connection
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 540043413b Xnest: use XCB for event loop
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 4fc95145ab Xnest: drop xnestWindowExposures micro-optimization
xnestWindowExposures() is a micro-optimization for the specific case that
a newly created window receives exposure events (from our upstream server)
inside the region we're already exposing on our own (miWindowExposures()):
it peeks the Xlib event queue for all expose events, checks whether their
areas are inside our exposure region and requeue's those that aren't.

Unfortunately, this depends on Xlib's internal queue mechamism, thus standing
in the way of moving to XCB (which doesn't have that).

Removing this doens't seem to make any practical difference, even with
demanding applications like GIMP. The only cost is potentially having some
initial window content painted twice, *if* the application really draws
something complicated right after creating the window.

*If* there'll really be a demand for such an optimization some day, it can
be reimplemented without any message queue: just redirecting all expose events
into recording them in a region, which is flushed out later. But for now,
there really doesn't seem to be any practical need for that.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 546ae43250 Xnest: split event handler
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 0df9c49314 Xnest: xnestCollectEvents(): scope local variables
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult cd0b53a950 Xnest: replace XConnectionNumber() by xcb_get_file_descriptor()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult e391aa2d71 Xnest: replace XReparentWindow() by xcb_reparent_window()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 608650a95e Xnest: drop using XLoadQueryFont()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult e1ab85e768 Xnest: replace XTextWidth[16]() by own implementation
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult b333dd017e Xnest: load fonts via xcb
FIXME: support xf86bigfont extension
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult b5ec55f862 Xnest: drop xnestFont() macro
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 2db318a341 Xnest: drop xnestFontStruct() macro
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 17b27b2ec3 Xnest: replace XQueryBestSize() by xcb_query_best_size()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult b51dd9e492 Xnest: replace X(Un)InstallColormap() by xcb_(un)install_colormap()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult a8410a0670 Xnest: drop obsolete XGetVisualInfo() call and reundant colormaps
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 825397cbfc Xnest: drop obsolete Visual.c
The whole file now has become obsolete, so drop it.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 143c1e0648 Xnest: use new lookup table for visuals and cmaps mappings
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 0913ee24d0 Xnest: screen: record visuals and cmaps in separate table
Record the associations between host's and our visuals as well their
corresponding cmaps in a global table, which's used later for lookups.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 23d541fbba Xnest: screen: use xcb setup data for retrieving upstream visuals
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult c6ca7b64f2 Xnest: fix memleak on user specified depth
Buffer overflow may happen on user specificed different depth/class:

xnestOpenScreen() looks into the wrong table: it's local visuals[] array,
instead of the global (non-dedup'ed) list fetched by xlib. The visuals[]
array is *much* smaller (deduplicated) than the xnestVisuals[] array,
and xnestDefaultVisualIndex is likely to point outside of visual[]'s bounds.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult ecb8ca56b5 Xnest: screen move assigment between depths and visual assignment to own function
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 0042894dfb Xnest: replace XParseGeometry() by own implementation
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 7603a5d6c1 Xnest: replace XGetWindowAttributes() by xcb_get_geometry()
Use xcb function instead of Xlib, and also spare one additional
(unused) request.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 1730573423 Xnest: collect upstream window geometry in one xRectangle struct
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 8e2614fe8a Xnest: replace XGetKeyboardControl() by xcb_get_keyboard_control()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult 9e0615e54f Xnest: replace XGetPointerMapping() by xcb_get_pointer_mapping()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult cfcea4ef79 Xnest: replace XGetPointerControl() by xcb_get_pointer_control()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:18 +02:00
Enrico Weigelt, metux IT consult bc1d6fe9de Xnest: replace XGetModifierMapping() by xcb_get_modifier_mapping()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:17 +02:00
Enrico Weigelt, metux IT consult 90b30fef64 Xnest: fetch keyboard mapping via xcb
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:17 +02:00
Enrico Weigelt, metux IT consult a1d0ad2155 Xnest: add own copy of fixed xcb_xkb_get_kbd_by_name()
This is a temporary measure, until xcbproto / libxcb is fixed:
keep an own copy of the fixed xcb_xkb_get_kbd_by_name(), renamed
as xcb_xkb_get_kbd_by_name_1().

Once xcbproto/libxcb is fixed (and new xcb release is out), this
commit can be reverted.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:39:13 +02:00
Enrico Weigelt, metux IT consult ebe499b2c4 Xnest: use xcb for retrieving keymap controls
This needs fix in xcbproto:

https://gitlab.freedesktop.org/xorg/proto/xcbproto/-/merge_requests/49

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult f702a02931 Xnest: replace XSelectInput() by xcb_change_window_attributes()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 801716a695 Xnest: replace XSetStandardProperties() by xcb functions
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 73953d49f9 Xnest: fetch supported pixmap formats from xcb setup data
There's even no need to keep our own copies, since we can ask XCB's
copy any time.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 92a52d0190 Xnest: fetch allowed screen depths from xcb screen info
There's even no need to keep our own copies, since we can ask XCB's
copy any time.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 8eddaa62ce Xnest: Pixmap: replace XGetImage() by xcb_get_image()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult ac34412efd Xnest: GC: replace XGetImage() by xcb_get_image()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult d3bafdf49f Xnest: replace XDestroyWindow() by xnest_destroy_window()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 2cd8b6c285 Xnest: replace XCreatePixmapFromBitmapData() by xcb_put_image()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 4a7a6cfb8d Xnest: replace XCreateBitmapFromData() by xcb_put_image()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult cce1ef3b95 Xnest: replace XDefineCursor() by xcb_change_window_attributes()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 072ac1ffdc Xnest: replace xnestRecolorCursor() by xcb_recolor_cursor()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult d059954952 Xnest: replace XFreeCursor() by xcb_free_cursor()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult edc514e2bd Xnest: replace XStoreColors() by xcb_store_colors()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult fd607858da Xnest: replace XQueryColors() by xcb_query_colors()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 4d24903dfb Xnest: replace XSetWindowColormap() by xcb_change_window_attributes()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult cde9d848d6 Xnest: replace XSetWMColormapWindows() by xcb_icccm_set_wm_colormap_windows_checked()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 3aa6daef7e Xnest: use XIDs directly, instead of Xlib's GC
Now that no Xlib drawing functions used anymore, we can finally switch over
to using GC XID's directly, instead of Xlib's GC struct.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult aee6eefbd4 Xnest: GC: set stipple filling via xcb_change_gc
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 710a60406c Xnest: replace XSetClipMask() by xcb_change_gc()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult c2215260a8 Xnest: replace XSetClipRectangles() by xnset_set_clip_rectangles()
Use XCB for setting clip rectangles.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult a26ca8e9bb Xnest: replace XSetDashes() by xnest_set_dashes()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 8a068eb15a Xnest: replace XChangeGC() by xcb_change_gc()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult db2743387b Xnest: replace XChangeKeyboardControl() by xcb_change_keyboard_control()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 1795698202 Xnest: replace XChangePointerControl() by xcb_change_pointer_control
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 315469160c Xnest: replace XSetWindowAttributes struct by own type
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 70acda3fba Xnest: replace XChangeWindowAttributes() by xcb_change_window_attributes()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 6d12f08fb2 Xnest: replace XDrawImageString() by xcb_image_text_8()
Replace XDrawImageString() by xcb_image_text_8(), as well as their 16-bit
counterparts.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 463dd69d9b Xnest: replace XDrawString[8|16]() by xcb_poly_text_[8|16]()
Replace XDrawString8() by xcb_poly_text_8(), as well as XDrawString16()
by xcb_poly_text_16(). Some care needs to be taken to prepend the xTextElt
header before sending the request out.

GC operation handlers don't need to care about poly-strings or length
above 254, as this is already handled by their caller, doPolyText().

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 0fdcadba09 Xnest: replace XFillRectangles() by xcb_poly_fill_rectangle()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 37d6d3ae98 Xnest: directly pass ClearArea request to upstream server
Instead of going through mi machinery, just pass the ClearArea
request to the upstream window.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 6aef795cc3 Xnest: replace XFillArcs() by xcb_poly_fill_arc()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 4156c3ed2b Xnest: replace XFillPolygon() by xcb_fill_poly()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult d5b26664f7 Xnest: replace XCopyPlane() by xcb_copy_plane()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 5557fe78a5 Xnest: replace XCopyArea() by xcb_copy_area()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult feb70bfcc3 Xnest: replace XDrawArcs() by xcb_poly_arc()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult da897336e7 Xnest: replace XDrawRectangles() by xcb_poly_rectangle()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 84926b8c55 Xnest: replace XDrawSegments() by xcb_poly_segment()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult a18d509fa3 Xnest: replace XDrawLines() by xcb_poly_line()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult d97f059bb8 Xnest: replace XDrawPoints() by xcb_poly_point()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult ad7558aeda Xnest: replace XCreateColormap() / XFreeColormap() by xcb
Use xcb_create_colormap() and XFreeColormap() instead of XCreateColormap()
and XFreeColormap().

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult d1cd3b5ce5 Xnest: use xcb instead of XShapeCombineRegion() and XShapeCombineMask()
Using xcb_shape_rectangles() and xcb_shape_mask() instead of Xlib's
XShapeCombineRegion() and XShapeCombineMask().

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult c9cf170a19 Xnest: use xcb_put_image() for PutImage requests
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 9df52bc2fe Xnest: use xcb_put_image() for creating cursors
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 813ab17323 Xnest: replace XCreatePixmapCursor() by xcb_create_cursor()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 9cf63422e2 xnest: replace XConfigureWindow() calls by xcb_configure_window()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult e30eefaa43 Xnest: use xcb for creating / destroying pixmaps
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 9f87bef81a Xnest: replace XBell() by xcb_bell()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 1314cbc8d4 Xnest: use xcb for (un)mapping windows
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 1ab416220d Xnest: replace XCreateWindow() by use xcb_create_window()
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult d7e5f08aa8 Xnest: converter from XSetWindowAttributes struct to uint32_t list
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 2ef0038355 Xnest: fetch root visual ID from screen data
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult cf9eefa25a Xnest: fetch keycode min/max from setup data
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 51b156e600 Xnest: fetch image metrics from xcb connection setup data
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult ec5254e80d Xnest: fetch default screen's root window from screen info
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 8281c536c1 Xnest: add helper for retrieving GC XID on upstream connection
Upcoming patches will need to retieve GC's XIDs on the upstream connection.
Moving this out into separate .c file, in order to not creating more
dependencies on Xlib headers, which we wanna get rid of.

For now, looking at the Xlib GC structure, attached to our DDX GCs.
When all users of the Xlib GC have gone (ie. moved all consumers to xcb),
we'll create the GC via xcb directly, thus replacing the Xlib GC struct
by XID - the interface of this helper will remain the same.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult a883e7a9e8 Xnest: fetch default colormap from xcb screen info
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 6b205756dc Xnest: fetch root window depth from screen info
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 9d964552f3 Xnest: fetch display size from xcb setup data
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 4d914beb6b Xnest: fetch BlackPixel and WhitePixel from xcb setup data
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 9dd8e84b8a Xnest: fetch xcb setup data
Fetching the setup data from xcb instead of Xlib, storing in our own struct,
holding all information needed for one particular upstream connection.
For now, there's only one, but future multi-upstream implementation will
change this to an array (and storing pointers to particular upstream in
various places).

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 0300295de5 Xnest: use XCB_EVENT_MASK_* defines
Use xcb's defines instead of Xlib's ones.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult e744208359 Xnest: use XCB*_NONE instead of None
Use xcb's defines instead of Xlib's ones.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult e4844fe72c Xnest: use XCB_BACK_PIXMAP_* defines
Use xcb's defines instead of Xlib's ones.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 81349772b3 xnest: replace ExposureMask by XCB_EVENT_MASK_EXPOSURE
Use xcb's defines instead of Xlib's ones.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 39cd6ff298 Xnest: replace NotUseful by XCB_BACKING_STORE_NOT_USEFUL
Use xcb's defines instead of Xlib's ones.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult fd8d455c5c Xnest: use XCB_CONFIG_WINDOW_* defines instead of CW*
Use xcb's defines instead of Xlib's ones.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult f9d5e6c318 Xnest: use XCB_CW_* defines instead of CW*
Use XCB's defines instead of Xlib's ones.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 428c23afaf Xnest: add xcb and x11-xcb as dependency
In order to transition to XCB, we need to link xcb, but temporarily
also x11-xcb.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 93ec4c8613 (submit/xnest-expose-events) Xnest: fix broken exposure events
Xnest fails to properly pass through expose events: the coordinates are
miscalculated in xnestCollectExposures(), before miSendExposures() is called.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1735
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/132
Fixes: 605e6764df - Fix Motif menu drawing in Xnest
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult f12944ce12 (submit/xnest-fix-unnecessary-include) Xnest: Keyboard: drop unnecessary include
<X11/extensions/XKBconfig.h> isn't needed, so drop it.

Fixes: d568221710 - XFree86 4.3.0.1
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 449b6ad6e0 (submit/xnest-bool) Xnest: use Xorg's TRUE/FALSE instead of Xlib's True/False
Use Xserver's defines instead of Xlib's ones. The values are the same.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 87c328e81b (submit/xnest-fix-missing-guards) Xnest: add guards to Xnest.h
protect it from duplicate inclusion.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 05f8ca8d26 (submit/xnest-XNGC.h-fix-missing-includes) Xnest: XNGC.h: add missing includes
This header makes use of types and functions defined in gcstruct.h and
privates.h. It should include them, instead of demanding it's consumers
having done that before including this file.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:54 +02:00
Enrico Weigelt, metux IT consult 23e5868713 (submit/xnest-fix-missing-include-colormap.h) Xnest: Display.h: fix missing include of colormap.h
Needs some types (eg. Pixel) from colormap.h

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-26 14:21:02 +02:00
31 changed files with 2380 additions and 1277 deletions

View File

@ -28,29 +28,25 @@ is" without express or implied warranty.
#include "scrnintstr.h"
#include "servermd.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Args.h"
char *xnestDisplayName = NULL;
Bool xnestSynchronize = False;
Bool xnestFullGeneration = False;
Bool xnestFullGeneration = FALSE;
int xnestDefaultClass;
Bool xnestUserDefaultClass = False;
Bool xnestUserDefaultClass = FALSE;
int xnestDefaultDepth;
Bool xnestUserDefaultDepth = False;
Bool xnestSoftwareScreenSaver = False;
int xnestX;
int xnestY;
unsigned int xnestWidth;
unsigned int xnestHeight;
Bool xnestUserDefaultDepth = FALSE;
Bool xnestSoftwareScreenSaver = FALSE;
xRectangle xnestGeometry = { 0 };
int xnestUserGeometry = 0;
int xnestBorderWidth;
Bool xnestUserBorderWidth = False;
Bool xnestUserBorderWidth = FALSE;
char *xnestWindowName = NULL;
int xnestNumScreens = 0;
Bool xnestDoDirectColormaps = False;
Bool xnestDoDirectColormaps = FALSE;
Window xnestParentWindow = 0;
int
@ -63,44 +59,40 @@ ddxProcessArgument(int argc, char *argv[], int i)
}
return 0;
}
if (!strcmp(argv[i], "-sync")) {
xnestSynchronize = True;
return 1;
}
if (!strcmp(argv[i], "-full")) {
xnestFullGeneration = True;
xnestFullGeneration = TRUE;
return 1;
}
if (!strcmp(argv[i], "-class")) {
if (++i < argc) {
if (!strcmp(argv[i], "StaticGray")) {
xnestDefaultClass = StaticGray;
xnestUserDefaultClass = True;
xnestUserDefaultClass = TRUE;
return 2;
}
else if (!strcmp(argv[i], "GrayScale")) {
xnestDefaultClass = GrayScale;
xnestUserDefaultClass = True;
xnestUserDefaultClass = TRUE;
return 2;
}
else if (!strcmp(argv[i], "StaticColor")) {
xnestDefaultClass = StaticColor;
xnestUserDefaultClass = True;
xnestUserDefaultClass = TRUE;
return 2;
}
else if (!strcmp(argv[i], "PseudoColor")) {
xnestDefaultClass = PseudoColor;
xnestUserDefaultClass = True;
xnestUserDefaultClass = TRUE;
return 2;
}
else if (!strcmp(argv[i], "TrueColor")) {
xnestDefaultClass = TrueColor;
xnestUserDefaultClass = True;
xnestUserDefaultClass = TRUE;
return 2;
}
else if (!strcmp(argv[i], "DirectColor")) {
xnestDefaultClass = DirectColor;
xnestUserDefaultClass = True;
xnestUserDefaultClass = TRUE;
return 2;
}
}
@ -109,7 +101,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
if (!strcmp(argv[i], "-cc")) {
if (++i < argc && sscanf(argv[i], "%i", &xnestDefaultClass) == 1) {
if (xnestDefaultClass >= 0 && xnestDefaultClass <= 5) {
xnestUserDefaultClass = True;
xnestUserDefaultClass = TRUE;
/* lex the OS layer process it as well, so return 0 */
}
}
@ -118,22 +110,19 @@ ddxProcessArgument(int argc, char *argv[], int i)
if (!strcmp(argv[i], "-depth")) {
if (++i < argc && sscanf(argv[i], "%i", &xnestDefaultDepth) == 1) {
if (xnestDefaultDepth > 0) {
xnestUserDefaultDepth = True;
xnestUserDefaultDepth = TRUE;
return 2;
}
}
return 0;
}
if (!strcmp(argv[i], "-sss")) {
xnestSoftwareScreenSaver = True;
xnestSoftwareScreenSaver = TRUE;
return 1;
}
if (!strcmp(argv[i], "-geometry")) {
if (++i < argc) {
xnestUserGeometry = XParseGeometry(argv[i],
&xnestX, &xnestY,
&xnestWidth, &xnestHeight);
if (xnestUserGeometry)
if (xnestParseGeometry(argv[i], &xnestGeometry))
return 2;
}
return 0;
@ -141,7 +130,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
if (!strcmp(argv[i], "-bw")) {
if (++i < argc && sscanf(argv[i], "%i", &xnestBorderWidth) == 1) {
if (xnestBorderWidth >= 0) {
xnestUserBorderWidth = True;
xnestUserBorderWidth = TRUE;
return 2;
}
}
@ -167,7 +156,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
return 0;
}
if (!strcmp(argv[i], "-install")) {
xnestDoDirectColormaps = True;
xnestDoDirectColormaps = TRUE;
return 1;
}
if (!strcmp(argv[i], "-parent")) {
@ -183,7 +172,6 @@ void
ddxUseMsg(void)
{
ErrorF("-display string display name of the real server\n");
ErrorF("-sync sinchronize with the real server\n");
ErrorF("-full utilize full regeneration\n");
ErrorF("-class string default visual class\n");
ErrorF("-depth int default depth\n");

View File

@ -19,17 +19,13 @@ is" without express or implied warranty.
#include <X11/Xdefs.h>
extern char *xnestDisplayName;
extern Bool xnestSynchronize;
extern Bool xnestFullGeneration;
extern int xnestDefaultClass;
extern Bool xnestUserDefaultClass;
extern int xnestDefaultDepth;
extern Bool xnestUserDefaultDepth;
extern Bool xnestSoftwareScreenSaver;
extern int xnestX;
extern int xnestY;
extern unsigned int xnestWidth;
extern unsigned int xnestHeight;
extern xRectangle xnestGeometry;
extern int xnestUserGeometry;
extern int xnestBorderWidth;
extern Bool xnestUserBorderWidth;

View File

@ -26,15 +26,16 @@ is" without express or implied warranty.
#include "colormapst.h"
#include "resource.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Screen.h"
#include "Color.h"
#include "Visual.h"
#include "XNWindow.h"
#include "Args.h"
#include <xcb/xcb_icccm.h>
DevPrivateKeyRec xnestColormapPrivateKeyRec;
static DevPrivateKeyRec cmapScrPrivateKeyRec;
@ -44,59 +45,79 @@ static DevPrivateKeyRec cmapScrPrivateKeyRec;
#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
static Bool loadColormap(ColormapPtr pCmap, int ncolors, uint32_t *colors)
{
xcb_generic_error_t *err = NULL;
xcb_query_colors_reply_t *reply = xcb_query_colors_reply(
xnestUpstreamInfo.conn,
xcb_query_colors(
xnestUpstreamInfo.conn,
xnestColormap(pCmap),
ncolors,
colors),
&err);
if (!reply) {
LogMessage(X_WARNING, "loadColormap: missing reply for QueryColors request\n");
free(colors);
return FALSE;
}
if (xcb_query_colors_colors_length(reply) != ncolors) {
LogMessage(X_WARNING, "loadColormap: received wrong number of entries: %d - expected %d\n",
xcb_query_colors_colors_length(reply), ncolors);
free(reply);
free(colors);
return FALSE;
}
xcb_rgb_t *rgb = xcb_query_colors_colors(reply);
for (int i = 0; i < ncolors; i++) {
pCmap->red[i].co.local.red = rgb[i].red;
pCmap->green[i].co.local.green = rgb[i].green;
pCmap->blue[i].co.local.blue = rgb[i].blue;
}
free(colors);
free(reply);
return TRUE;
}
Bool
xnestCreateColormap(ColormapPtr pCmap)
{
VisualPtr pVisual;
XColor *colors;
int i, ncolors;
Pixel red, green, blue;
Pixel redInc, greenInc, blueInc;
VisualPtr pVisual = pCmap->pVisual;
int ncolors = pVisual->ColormapEntries;
pVisual = pCmap->pVisual;
ncolors = pVisual->ColormapEntries;
uint32_t const cmap = xcb_generate_id(xnestUpstreamInfo.conn);
xnestColormapPriv(pCmap)->colormap = cmap;
xnestColormapPriv(pCmap)->colormap =
XCreateColormap(xnestDisplay,
xcb_create_colormap(xnestUpstreamInfo.conn,
(pVisual->class & DynamicClass) ? XCB_COLORMAP_ALLOC_ALL : XCB_COLORMAP_ALLOC_NONE,
cmap,
xnestDefaultWindows[pCmap->pScreen->myNum],
xnestVisual(pVisual),
(pVisual->class & DynamicClass) ? AllocAll : AllocNone);
xnest_visual_map_to_host(pVisual->vid));
switch (pVisual->class) {
case StaticGray: /* read only */
colors = xallocarray(ncolors, sizeof(XColor));
for (i = 0; i < ncolors; i++)
colors[i].pixel = i;
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
for (i = 0; i < ncolors; i++) {
pCmap->red[i].co.local.red = colors[i].red;
pCmap->red[i].co.local.green = colors[i].red;
pCmap->red[i].co.local.blue = colors[i].red;
}
free(colors);
break;
case StaticColor: /* read only */
colors = xallocarray(ncolors, sizeof(XColor));
for (i = 0; i < ncolors; i++)
colors[i].pixel = i;
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
for (i = 0; i < ncolors; i++) {
pCmap->red[i].co.local.red = colors[i].red;
pCmap->red[i].co.local.green = colors[i].green;
pCmap->red[i].co.local.blue = colors[i].blue;
}
free(colors);
break;
{
uint32_t *colors = malloc(ncolors * sizeof(uint32_t));
for (int i = 0; i < ncolors; i++)
colors[i] = i;
return loadColormap(pCmap, ncolors, colors);
}
break;
case TrueColor: /* read only */
colors = xallocarray(ncolors, sizeof(XColor));
red = green = blue = 0L;
redInc = lowbit(pVisual->redMask);
greenInc = lowbit(pVisual->greenMask);
blueInc = lowbit(pVisual->blueMask);
for (i = 0; i < ncolors; i++) {
colors[i].pixel = red | green | blue;
{
uint32_t *colors = malloc(ncolors * sizeof(uint32_t));
Pixel red = 0, redInc = lowbit(pVisual->redMask);
Pixel green = 0, greenInc = lowbit(pVisual->greenMask);
Pixel blue = 0, blueInc = lowbit(pVisual->blueMask);
for (int i = 0; i < ncolors; i++) {
colors[i] = red | green | blue;
red += redInc;
if (red > pVisual->redMask)
red = 0L;
@ -107,14 +128,9 @@ xnestCreateColormap(ColormapPtr pCmap)
if (blue > pVisual->blueMask)
blue = 0L;
}
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
for (i = 0; i < ncolors; i++) {
pCmap->red[i].co.local.red = colors[i].red;
pCmap->green[i].co.local.green = colors[i].green;
pCmap->blue[i].co.local.blue = colors[i].blue;
}
free(colors);
break;
return loadColormap(pCmap, ncolors, colors);
}
break;
case GrayScale: /* read and write */
break;
@ -126,17 +142,17 @@ xnestCreateColormap(ColormapPtr pCmap)
break;
}
return True;
return TRUE;
}
void
xnestDestroyColormap(ColormapPtr pCmap)
{
XFreeColormap(xnestDisplay, xnestColormap(pCmap));
xcb_free_colormap(xnestUpstreamInfo.conn, xnestColormap(pCmap));
}
#define SEARCH_PREDICATE \
(xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
(xnestWindow(pWin) != XCB_WINDOW_NONE && wColormap(pWin) == icws->cmapIDs[i])
static int
xnestCountInstalledColormapWindows(WindowPtr pWin, void *ptr)
@ -175,19 +191,19 @@ static Bool
xnestSameInstalledColormapWindows(Window *windows, int numWindows)
{
if (xnestNumOldInstalledColormapWindows != numWindows)
return False;
return FALSE;
if (xnestOldInstalledColormapWindows == windows)
return True;
return TRUE;
if (xnestOldInstalledColormapWindows == NULL || windows == NULL)
return False;
return FALSE;
if (memcmp(xnestOldInstalledColormapWindows, windows,
numWindows * sizeof(Window)))
return False;
return FALSE;
return True;
return TRUE;
}
void
@ -217,22 +233,10 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
free(xnestOldInstalledColormapWindows);
#ifdef _XSERVER64
{
int i;
Window64 *windows = xallocarray(numWindows, sizeof(Window64));
for (i = 0; i < numWindows; ++i)
windows[i] = icws.windows[i];
XSetWMColormapWindows(xnestDisplay,
xnestDefaultWindows[pScreen->myNum], windows,
numWindows);
free(windows);
}
#else
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
icws.windows, numWindows);
#endif
xnestWMColormapWindows(xnestUpstreamInfo.conn,
xnestDefaultWindows[pScreen->myNum],
icws.windows,
numWindows);
xnestOldInstalledColormapWindows = icws.windows;
xnestNumOldInstalledColormapWindows = icws.numWindows;
@ -244,13 +248,12 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
*/
if (icws.numWindows) {
WindowPtr pWin;
Visual *visual;
ColormapPtr pCmap;
pWin = xnestWindowPtr(icws.windows[0]);
visual = xnestVisualFromID(pScreen, wVisual(pWin));
if (visual == xnestDefaultVisual(pScreen))
if (xnest_visual_map_to_host(wVisual(pWin)) ==
xnest_visual_map_to_host(pScreen->rootVisual))
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
X11_RESTYPE_COLORMAP, serverClient,
DixUseAccess);
@ -259,9 +262,11 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
pScreen->defColormap, X11_RESTYPE_COLORMAP,
serverClient, DixUseAccess);
XSetWindowColormap(xnestDisplay,
xnestDefaultWindows[pScreen->myNum],
xnestColormap(pCmap));
uint32_t cmap = xnestColormap(pCmap);
xcb_change_window_attributes(xnestUpstreamInfo.conn,
xnestDefaultWindows[pScreen->myNum],
XCB_CW_COLORMAP,
&cmap);
}
#endif /* DUMB_WINDOW_MANAGERS */
}
@ -274,19 +279,10 @@ xnestSetScreenSaverColormapWindow(ScreenPtr pScreen)
{
free(xnestOldInstalledColormapWindows);
#ifdef _XSERVER64
{
Window64 window;
window = xnestScreenSaverWindows[pScreen->myNum];
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
&window, 1);
xnestScreenSaverWindows[pScreen->myNum] = window;
}
#else
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
&xnestScreenSaverWindows[pScreen->myNum], 1);
#endif /* _XSERVER64 */
xnestWMColormapWindows(xnestUpstreamInfo.conn,
xnestDefaultWindows[pScreen->myNum],
&xnestScreenSaverWindows[pScreen->myNum],
1);
xnestOldInstalledColormapWindows = NULL;
xnestNumOldInstalledColormapWindows = 0;
@ -311,7 +307,7 @@ xnestDirectInstallColormaps(ScreenPtr pScreen)
dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], X11_RESTYPE_COLORMAP,
serverClient, DixInstallAccess);
if (pCmap)
XInstallColormap(xnestDisplay, xnestColormap(pCmap));
xcb_install_colormap(xnestUpstreamInfo.conn, xnestColormap(pCmap));
}
}
@ -332,7 +328,7 @@ xnestDirectUninstallColormaps(ScreenPtr pScreen)
dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], X11_RESTYPE_COLORMAP,
serverClient, DixUninstallAccess);
if (pCmap)
XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
xcb_uninstall_colormap(xnestUpstreamInfo.conn, xnestColormap(pCmap));
}
}
@ -345,7 +341,7 @@ xnestInstallColormap(ColormapPtr pCmap)
xnestDirectUninstallColormaps(pCmap->pScreen);
/* Uninstall pInstalledMap. Notify all interested parties. */
if (pOldCmap != (ColormapPtr) None)
if (pOldCmap != (ColormapPtr) XCB_COLORMAP_NONE)
WalkTree(pCmap->pScreen, TellLostMap, (void *) &pOldCmap->mid);
SetInstalledColormap(pCmap->pScreen, pCmap);
@ -372,7 +368,7 @@ xnestUninstallColormap(ColormapPtr pCmap)
}
}
static Bool xnestInstalledDefaultColormap = False;
static Bool xnestInstalledDefaultColormap = FALSE;
int
xnestListInstalledColormaps(ScreenPtr pScreen, Colormap * pCmapIDs)
@ -389,25 +385,10 @@ void
xnestStoreColors(ColormapPtr pCmap, int nColors, xColorItem * pColors)
{
if (pCmap->pVisual->class & DynamicClass)
#ifdef _XSERVER64
{
int i;
XColor *pColors64 = xallocarray(nColors, sizeof(XColor));
for (i = 0; i < nColors; ++i) {
pColors64[i].pixel = pColors[i].pixel;
pColors64[i].red = pColors[i].red;
pColors64[i].green = pColors[i].green;
pColors64[i].blue = pColors[i].blue;
pColors64[i].flags = pColors[i].flags;
}
XStoreColors(xnestDisplay, xnestColormap(pCmap), pColors64, nColors);
free(pColors64);
}
#else
XStoreColors(xnestDisplay, xnestColormap(pCmap),
(XColor *) pColors, nColors);
#endif
xcb_store_colors(xnestUpstreamInfo.conn,
xnestColormap(pCmap),
nColors,
(xcb_coloritem_t*) pColors);
}
void
@ -474,7 +455,7 @@ xnestCreateDefaultColormap(ScreenPtr pScreen)
(pVisual->class & DynamicClass) ? AllocNone : AllocAll,
0)
!= Success)
return False;
return FALSE;
wp = pScreen->whitePixel;
bp = pScreen->blackPixel;
@ -486,7 +467,7 @@ xnestCreateDefaultColormap(ScreenPtr pScreen)
pScreen->blackPixel = bp;
(*pScreen->InstallColormap) (pCmap);
xnestInstalledDefaultColormap = True;
xnestInstalledDefaultColormap = TRUE;
return True;
return TRUE;
}

View File

@ -28,12 +28,11 @@ is" without express or implied warranty.
#include "servermd.h"
#include "mipointrst.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Screen.h"
#include "XNCursor.h"
#include "Visual.h"
#include "Keyboard.h"
#include "Args.h"
@ -42,97 +41,87 @@ xnestCursorFuncRec xnestCursorFuncs = { NULL };
Bool
xnestRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
{
XImage *ximage;
Pixmap source, mask;
XColor fg_color, bg_color;
unsigned long valuemask;
XGCValues values;
uint32_t valuemask = XCB_GC_FUNCTION | XCB_GC_PLANE_MASK | XCB_GC_FOREGROUND
| XCB_GC_BACKGROUND | XCB_GC_CLIP_MASK;
valuemask = GCFunction |
GCPlaneMask | GCForeground | GCBackground | GCClipMask;
XnGCValues values = {
.function = XCB_GX_COPY,
.plane_mask = ((unsigned long)~0L),
.foreground = 1L,
};
values.function = GXcopy;
values.plane_mask = AllPlanes;
values.foreground = 1L;
values.background = 0L;
values.clip_mask = None;
xnChangeGC(xnestUpstreamInfo.conn, xnestBitmapGC, values, valuemask);
XChangeGC(xnestDisplay, xnestBitmapGC, valuemask, &values);
uint32_t const winId = xnestDefaultWindows[pScreen->myNum];
source = XCreatePixmap(xnestDisplay,
xnestDefaultWindows[pScreen->myNum],
pCursor->bits->width, pCursor->bits->height, 1);
Pixmap const source = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_pixmap(xnestUpstreamInfo.conn, 1, source, winId, pCursor->bits->width, pCursor->bits->height);
mask = XCreatePixmap(xnestDisplay,
xnestDefaultWindows[pScreen->myNum],
pCursor->bits->width, pCursor->bits->height, 1);
Pixmap const mask = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_pixmap(xnestUpstreamInfo.conn, 1, mask, winId, pCursor->bits->width, pCursor->bits->height);
ximage = XCreateImage(xnestDisplay,
xnestDefaultVisual(pScreen),
1, XYBitmap, 0,
(char *) pCursor->bits->source,
pCursor->bits->width,
pCursor->bits->height, BitmapPad(xnestDisplay), 0);
int const pixmap_len = BitmapBytePad(pCursor->bits->width) * pCursor->bits->height;
XPutImage(xnestDisplay, source, xnestBitmapGC, ximage,
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
xcb_put_image(xnestUpstreamInfo.conn,
XCB_IMAGE_FORMAT_XY_BITMAP,
source,
xnestBitmapGC,
pCursor->bits->width,
pCursor->bits->height,
0, // x
0, // y
0, // left_pad
1, // depth
pixmap_len,
(uint8_t*) pCursor->bits->source);
XFree(ximage);
ximage = XCreateImage(xnestDisplay,
xnestDefaultVisual(pScreen),
1, XYBitmap, 0,
(char *) pCursor->bits->mask,
pCursor->bits->width,
pCursor->bits->height, BitmapPad(xnestDisplay), 0);
XPutImage(xnestDisplay, mask, xnestBitmapGC, ximage,
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
XFree(ximage);
fg_color.red = pCursor->foreRed;
fg_color.green = pCursor->foreGreen;
fg_color.blue = pCursor->foreBlue;
bg_color.red = pCursor->backRed;
bg_color.green = pCursor->backGreen;
bg_color.blue = pCursor->backBlue;
xcb_put_image(xnestUpstreamInfo.conn,
XCB_IMAGE_FORMAT_XY_BITMAP,
mask,
xnestBitmapGC,
pCursor->bits->width,
pCursor->bits->height,
0, // x
0, // y
0, // left_pad
1, // depth
pixmap_len,
(uint8_t*) pCursor->bits->mask);
xnestSetCursorPriv(pCursor, pScreen, calloc(1, sizeof(xnestPrivCursor)));
xnestCursor(pCursor, pScreen) =
XCreatePixmapCursor(xnestDisplay, source, mask, &fg_color, &bg_color,
pCursor->bits->xhot, pCursor->bits->yhot);
uint32_t cursor = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_cursor(xnestUpstreamInfo.conn, cursor, source, mask,
pCursor->foreRed, pCursor->foreGreen, pCursor->foreBlue,
pCursor->backRed, pCursor->backGreen, pCursor->backBlue,
pCursor->bits->xhot, pCursor->bits->yhot);
XFreePixmap(xnestDisplay, source);
XFreePixmap(xnestDisplay, mask);
xnestCursor(pCursor, pScreen) = cursor;
return True;
xcb_free_pixmap(xnestUpstreamInfo.conn, source);
xcb_free_pixmap(xnestUpstreamInfo.conn, mask);
return TRUE;
}
Bool
xnestUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
{
XFreeCursor(xnestDisplay, xnestCursor(pCursor, pScreen));
xcb_free_cursor(xnestUpstreamInfo.conn, xnestCursor(pCursor, pScreen));
free(xnestGetCursorPriv(pCursor, pScreen));
return True;
return TRUE;
}
void
xnestRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
{
XColor fg_color, bg_color;
fg_color.red = pCursor->foreRed;
fg_color.green = pCursor->foreGreen;
fg_color.blue = pCursor->foreBlue;
bg_color.red = pCursor->backRed;
bg_color.green = pCursor->backGreen;
bg_color.blue = pCursor->backBlue;
XRecolorCursor(xnestDisplay,
xnestCursor(pCursor, pScreen), &fg_color, &bg_color);
xcb_recolor_cursor(xnestUpstreamInfo.conn,
xnestCursor(pCursor, pScreen),
pCursor->foreRed,
pCursor->foreGreen,
pCursor->foreBlue,
pCursor->backRed,
pCursor->backGreen,
pCursor->backBlue);
}
void
@ -140,9 +129,12 @@ xnestSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x,
int y)
{
if (pCursor) {
XDefineCursor(xnestDisplay,
xnestDefaultWindows[pScreen->myNum],
xnestCursor(pCursor, pScreen));
uint32_t cursor = xnestCursor(pCursor, pScreen);
xcb_change_window_attributes(xnestUpstreamInfo.conn,
xnestDefaultWindows[pScreen->myNum],
XCB_CW_CURSOR,
&cursor);
}
}

View File

@ -30,7 +30,7 @@ is" without express or implied warranty.
#include "scrnintstr.h"
#include "servermd.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Init.h"
@ -39,173 +39,111 @@ is" without express or implied warranty.
#include "icon"
#include "screensaver"
Display *xnestDisplay = NULL;
XVisualInfo *xnestVisuals;
int xnestNumVisuals;
int xnestDefaultVisualIndex;
Colormap *xnestDefaultColormaps;
static uint16_t xnestNumDefaultColormaps;
int *xnestDepths;
int xnestNumDepths;
XPixmapFormatValues *xnestPixmapFormats;
int xnestNumPixmapFormats;
Pixel xnestBlackPixel;
Pixel xnestWhitePixel;
Drawable xnestDefaultDrawables[MAXDEPTH + 1];
Pixmap xnestIconBitmap;
Pixmap xnestScreenSaverPixmap;
XlibGC xnestBitmapGC;
unsigned long xnestEventMask;
static int _X_NORETURN
x_io_error_handler(Display * dpy)
{
ErrorF("Lost connection to X server: %s\n", strerror(errno));
CloseWellKnownConnections();
OsCleanup(1);
exit(1);
}
uint32_t xnestBitmapGC;
uint32_t xnestEventMask;
void
xnestOpenDisplay(int argc, char *argv[])
{
XVisualInfo vi;
long mask;
int i, j;
int i;
if (!xnestDoFullGeneration)
return;
XSetIOErrorHandler(x_io_error_handler);
xnestCloseDisplay();
xnestDisplay = XOpenDisplay(xnestDisplayName);
if (xnestDisplay == NULL)
FatalError("Unable to open display \"%s\".\n",
XDisplayName(xnestDisplayName));
if (xnestSynchronize)
XSynchronize(xnestDisplay, True);
mask = VisualScreenMask;
vi.screen = DefaultScreen(xnestDisplay);
xnestVisuals = XGetVisualInfo(xnestDisplay, mask, &vi, &xnestNumVisuals);
if (xnestNumVisuals == 0 || xnestVisuals == NULL)
FatalError("Unable to find any visuals.\n");
if (xnestUserDefaultClass || xnestUserDefaultDepth) {
xnestDefaultVisualIndex = UNDEFINED;
for (i = 0; i < xnestNumVisuals; i++)
if ((!xnestUserDefaultClass ||
xnestVisuals[i].class == xnestDefaultClass)
&&
(!xnestUserDefaultDepth ||
xnestVisuals[i].depth == xnestDefaultDepth)) {
xnestDefaultVisualIndex = i;
break;
}
if (xnestDefaultVisualIndex == UNDEFINED)
FatalError("Unable to find desired default visual.\n");
}
else {
vi.visualid = XVisualIDFromVisual(DefaultVisual(xnestDisplay,
DefaultScreen
(xnestDisplay)));
xnestDefaultVisualIndex = 0;
for (i = 0; i < xnestNumVisuals; i++)
if (vi.visualid == xnestVisuals[i].visualid)
xnestDefaultVisualIndex = i;
}
xnestNumDefaultColormaps = xnestNumVisuals;
xnestDefaultColormaps = xallocarray(xnestNumDefaultColormaps,
sizeof(Colormap));
for (i = 0; i < xnestNumDefaultColormaps; i++)
xnestDefaultColormaps[i] = XCreateColormap(xnestDisplay,
DefaultRootWindow
(xnestDisplay),
xnestVisuals[i].visual,
AllocNone);
xnestDepths = XListDepths(xnestDisplay, DefaultScreen(xnestDisplay),
&xnestNumDepths);
xnestPixmapFormats = XListPixmapFormats(xnestDisplay,
&xnestNumPixmapFormats);
xnestBlackPixel = BlackPixel(xnestDisplay, DefaultScreen(xnestDisplay));
xnestWhitePixel = WhitePixel(xnestDisplay, DefaultScreen(xnestDisplay));
if (!xnest_upstream_setup(xnestDisplayName))
FatalError("Unable to open display \"%s\".\n", xnestDisplayName);
if (xnestParentWindow != (Window) 0)
xnestEventMask = StructureNotifyMask;
xnestEventMask = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
else
xnestEventMask = 0L;
for (i = 0; i <= MAXDEPTH; i++)
xnestDefaultDrawables[i] = None;
xnestDefaultDrawables[i] = XCB_WINDOW_NONE;
for (i = 0; i < xnestNumPixmapFormats; i++)
for (j = 0; j < xnestNumDepths; j++)
if (xnestPixmapFormats[i].depth == 1 ||
xnestPixmapFormats[i].depth == xnestDepths[j]) {
xnestDefaultDrawables[xnestPixmapFormats[i].depth] =
XCreatePixmap(xnestDisplay, DefaultRootWindow(xnestDisplay),
1, 1, xnestPixmapFormats[i].depth);
xcb_format_t *fmt = xcb_setup_pixmap_formats(xnestUpstreamInfo.setup);
const xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(xnestUpstreamInfo.setup);
for(; fmt != fmtend; ++fmt) {
xcb_depth_iterator_t depth_iter;
for (depth_iter = xcb_screen_allowed_depths_iterator(xnestUpstreamInfo.screenInfo);
depth_iter.rem;
xcb_depth_next(&depth_iter))
{
if (fmt->depth == 1 || fmt->depth == depth_iter.data->depth) {
uint32_t pixmap = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_pixmap(xnestUpstreamInfo.conn,
fmt->depth,
pixmap,
xnestUpstreamInfo.screenInfo->root,
1, 1);
xnestDefaultDrawables[fmt->depth] = pixmap;
}
}
}
xnestBitmapGC = XCreateGC(xnestDisplay, xnestDefaultDrawables[1], 0L, NULL);
xnestBitmapGC = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_gc(xnestUpstreamInfo.conn,
xnestBitmapGC,
xnestDefaultDrawables[1],
0,
NULL);
if (!(xnestUserGeometry & XValue))
xnestX = 0;
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_X))
xnestGeometry.x = 0;
if (!(xnestUserGeometry & YValue))
xnestY = 0;
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_Y))
xnestGeometry.y = 0;
if (xnestParentWindow == 0) {
if (!(xnestUserGeometry & WidthValue))
xnestWidth = 3 * DisplayWidth(xnestDisplay,
DefaultScreen(xnestDisplay)) / 4;
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_WIDTH))
xnestGeometry.width = 3 * xnestUpstreamInfo.screenInfo->width_in_pixels / 4;
if (!(xnestUserGeometry & HeightValue))
xnestHeight = 3 * DisplayHeight(xnestDisplay,
DefaultScreen(xnestDisplay)) / 4;
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_HEIGHT))
xnestGeometry.height = 3 * xnestUpstreamInfo.screenInfo->height_in_pixels / 4;
}
if (!xnestUserBorderWidth)
xnestBorderWidth = 1;
xnestIconBitmap =
XCreateBitmapFromData(xnestDisplay,
DefaultRootWindow(xnestDisplay),
xnestCreateBitmapFromData(xnestUpstreamInfo.conn,
xnestUpstreamInfo.screenInfo->root,
(char *) icon_bits, icon_width, icon_height);
xnestScreenSaverPixmap =
XCreatePixmapFromBitmapData(xnestDisplay,
DefaultRootWindow(xnestDisplay),
xnestCreatePixmapFromBitmapData(xnestUpstreamInfo.conn,
xnestUpstreamInfo.screenInfo->root,
(char *) screensaver_bits,
screensaver_width,
screensaver_height,
xnestWhitePixel,
xnestBlackPixel,
DefaultDepth(xnestDisplay,
DefaultScreen(xnestDisplay)));
xnestUpstreamInfo.screenInfo->white_pixel,
xnestUpstreamInfo.screenInfo->black_pixel,
xnestUpstreamInfo.screenInfo->root_depth);
}
void
xnestCloseDisplay(void)
{
if (!xnestDoFullGeneration || !xnestDisplay)
if (!xnestDoFullGeneration || !xnestUpstreamInfo.conn)
return;
/*
If xnestDoFullGeneration all x resources will be destroyed upon closing
the display connection. There is no need to generate extra protocol.
*/
free(xnestVisualMap);
xnestVisualMap = NULL;
xnestNumVisualMap = 0;
free(xnestDefaultColormaps);
XFree(xnestVisuals);
XFree(xnestDepths);
XFree(xnestPixmapFormats);
XCloseDisplay(xnestDisplay);
xcb_disconnect(xnestUpstreamInfo.conn);
xnestUpstreamInfo.conn = NULL;
xnestUpstreamInfo.screenInfo = NULL;
xnestUpstreamInfo.setup = NULL;
}

View File

@ -15,28 +15,19 @@ is" without express or implied warranty.
#ifndef XNESTCOMMON_H
#define XNESTCOMMON_H
#include "colormap.h"
#define UNDEFINED -1
#define MAXDEPTH 32
#define MAXVISUALSPERDEPTH 256
extern Display *xnestDisplay;
extern XVisualInfo *xnestVisuals;
extern int xnestNumVisuals;
extern int xnestDefaultVisualIndex;
extern Colormap *xnestDefaultColormaps;
extern int xnestNumDefaultClormaps;
extern int *xnestDepths;
extern int xnestNumDepths;
extern XPixmapFormatValues *xnestPixmapFormats;
extern int xnestNumPixmapFormats;
extern Pixel xnestBlackPixel;
extern Pixel xnestWhitePixel;
extern Drawable xnestDefaultDrawables[MAXDEPTH + 1];
extern Pixmap xnestIconBitmap;
extern Pixmap xnestScreenSaverPixmap;
extern XlibGC xnestBitmapGC;
extern unsigned long xnestEventMask;
extern uint32_t xnestBitmapGC;
extern uint32_t xnestEventMask;
void xnestOpenDisplay(int argc, char *argv[]);
void xnestCloseDisplay(void);

View File

@ -31,7 +31,7 @@ is" without express or implied warranty.
#include "mi.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Args.h"
#include "Color.h"
@ -65,42 +65,6 @@ SetTimeSinceLastInputEvent(void)
lastEventTime = GetTimeInMillis();
}
static Bool
xnestExposurePredicate(Display * dpy, XEvent * event, char *args)
{
return event->type == Expose || event->type == ProcessedExpose;
}
static Bool
xnestNotExposurePredicate(Display * dpy, XEvent * event, char *args)
{
return !xnestExposurePredicate(dpy, event, args);
}
void
xnestCollectExposures(void)
{
XEvent X;
WindowPtr pWin;
RegionRec Rgn;
BoxRec Box;
while (XCheckIfEvent(xnestDisplay, &X, xnestExposurePredicate, NULL)) {
pWin = xnestWindowPtr(X.xexpose.window);
if (pWin && X.xexpose.width && X.xexpose.height) {
Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + X.xexpose.x;
Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + X.xexpose.y;
Box.x2 = Box.x1 + X.xexpose.width;
Box.y2 = Box.y1 + X.xexpose.height;
RegionInit(&Rgn, &Box, 1);
miSendExposures(pWin, &Rgn, Box.x2, Box.y2);
}
}
}
void
xnestQueueKeyEvent(int type, unsigned int keycode)
{
@ -108,78 +72,106 @@ xnestQueueKeyEvent(int type, unsigned int keycode)
QueueKeyboardEvents(xnestKeyboardDevice, type, keycode);
}
void
xnestCollectEvents(void)
{
XEvent X;
int valuators[2];
ValuatorMask mask;
ScreenPtr pScreen;
#define EVTYPE(tname) tname *ev = (tname*)event
while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
switch (X.type) {
static void
xnest_handle_event(xcb_generic_event_t *event)
{
if (!event)
return;
switch (event->response_type & ~0x80) {
case KeyPress:
xnestUpdateModifierState(X.xkey.state);
xnestQueueKeyEvent(KeyPress, X.xkey.keycode);
{
EVTYPE(xcb_key_press_event_t);
xnestUpdateModifierState(ev->state);
xnestQueueKeyEvent(KeyPress, ev->detail);
break;
}
case KeyRelease:
xnestUpdateModifierState(X.xkey.state);
xnestQueueKeyEvent(KeyRelease, X.xkey.keycode);
{
EVTYPE(xcb_key_release_event_t);
xnestUpdateModifierState(ev->state);
xnestQueueKeyEvent(KeyRelease, ev->detail);
break;
}
case ButtonPress:
{
ValuatorMask mask;
EVTYPE(xcb_button_press_event_t);
valuator_mask_set_range(&mask, 0, 0, NULL);
xnestUpdateModifierState(X.xkey.state);
xnestUpdateModifierState(ev->state);
lastEventTime = GetTimeInMillis();
QueuePointerEvents(xnestPointerDevice, ButtonPress,
X.xbutton.button, POINTER_RELATIVE, &mask);
ev->detail, POINTER_RELATIVE, &mask);
break;
}
case ButtonRelease:
{
ValuatorMask mask;
EVTYPE(xcb_button_release_event_t);
valuator_mask_set_range(&mask, 0, 0, NULL);
xnestUpdateModifierState(X.xkey.state);
xnestUpdateModifierState(ev->state);
lastEventTime = GetTimeInMillis();
QueuePointerEvents(xnestPointerDevice, ButtonRelease,
X.xbutton.button, POINTER_RELATIVE, &mask);
ev->detail, POINTER_RELATIVE, &mask);
break;
}
case MotionNotify:
valuators[0] = X.xmotion.x;
valuators[1] = X.xmotion.y;
{
EVTYPE(xcb_motion_notify_event_t);
ValuatorMask mask;
int valuators[2];
valuators[0] = ev->event_x;
valuators[1] = ev->event_y;
valuator_mask_set_range(&mask, 0, 2, valuators);
lastEventTime = GetTimeInMillis();
QueuePointerEvents(xnestPointerDevice, MotionNotify,
0, POINTER_ABSOLUTE, &mask);
break;
}
case FocusIn:
if (X.xfocus.detail != NotifyInferior) {
pScreen = xnestScreen(X.xfocus.window);
{
EVTYPE(xcb_focus_in_event_t);
if (ev->detail != NotifyInferior) {
ScreenPtr pScreen = xnestScreen(ev->event);
if (pScreen)
xnestDirectInstallColormaps(pScreen);
}
break;
}
case FocusOut:
if (X.xfocus.detail != NotifyInferior) {
pScreen = xnestScreen(X.xfocus.window);
{
EVTYPE(xcb_focus_out_event_t);
if (ev->detail != NotifyInferior) {
ScreenPtr pScreen = xnestScreen(ev->event);
if (pScreen)
xnestDirectUninstallColormaps(pScreen);
}
break;
}
case KeymapNotify:
break;
case EnterNotify:
if (X.xcrossing.detail != NotifyInferior) {
pScreen = xnestScreen(X.xcrossing.window);
{
EVTYPE(xcb_enter_notify_event_t);
if (ev->detail != NotifyInferior) {
ScreenPtr pScreen = xnestScreen(ev->event);
if (pScreen) {
NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x,
X.xcrossing.y);
valuators[0] = X.xcrossing.x;
valuators[1] = X.xcrossing.y;
ValuatorMask mask;
int valuators[2];
NewCurrentScreen(inputInfo.pointer, pScreen,
ev->event_x, ev->event_y);
valuators[0] = ev->event_x;
valuators[1] = ev->event_y;
valuator_mask_set_range(&mask, 0, 2, valuators);
lastEventTime = GetTimeInMillis();
QueuePointerEvents(xnestPointerDevice, MotionNotify,
@ -188,21 +180,28 @@ xnestCollectEvents(void)
}
}
break;
}
case LeaveNotify:
if (X.xcrossing.detail != NotifyInferior) {
pScreen = xnestScreen(X.xcrossing.window);
{
EVTYPE(xcb_leave_notify_event_t);
if (ev->detail != NotifyInferior) {
ScreenPtr pScreen = xnestScreen(ev->event);
if (pScreen) {
xnestDirectUninstallColormaps(pScreen);
}
}
break;
}
case DestroyNotify:
if (xnestParentWindow != (Window) 0 &&
X.xdestroywindow.window == xnestParentWindow)
{
xcb_destroy_notify_event_t *ev = (xcb_destroy_notify_event_t*)event;
if (xnestParentWindow &&
ev->window == xnestParentWindow)
exit(0);
break;
}
case CirculateNotify:
case ConfigureNotify:
@ -210,12 +209,65 @@ xnestCollectEvents(void)
case MapNotify:
case ReparentNotify:
case UnmapNotify:
case NoExpose:
break;
default:
ErrorF("xnest warning: unhandled event: %d\n", X.type);
break;
case Expose:
{
EVTYPE(xcb_expose_event_t);
WindowPtr pWin = xnestWindowPtr(ev->window);
if (pWin && ev->width && ev->height) {
RegionRec Rgn;
BoxRec Box = {
.x1 = pWin->drawable.x + wBorderWidth(pWin) + ev->x,
.y1 = pWin->drawable.y + wBorderWidth(pWin) + ev->y,
.x2 = Box.x1 + ev->width,
.y2 = Box.y1 + ev->height,
};
RegionInit(&Rgn, &Box, 1);
miSendExposures(pWin, &Rgn, Box.x1, Box.y1);
}
}
break;
case NoExpose:
ErrorF("xnest: received stray NoExpose\n");
break;
case GraphicsExpose:
ErrorF("xnest: received stray GraphicsExpose\n");
break;
default:
ErrorF("xnest warning: unhandled event: %d\n", event->response_type);
break;
}
}
void
xnestCollectEvents(void)
{
/* process queued events */
xnestEventQueue *tmp = NULL, *walk = NULL;
xorg_list_for_each_entry_safe(walk, tmp, &xnestUpstreamInfo.eventQueue.entry, entry) {
xnest_handle_event(walk->event);
xorg_list_del(&walk->entry);
free(walk->event);
free(walk);
}
xcb_flush(xnestUpstreamInfo.conn);
int err = xcb_connection_has_error(xnestUpstreamInfo.conn);
if (err) {
ErrorF("Xnest: upstream connection error: %d\n", err);
exit(0);
}
/* fetch new events from xcb */
xcb_generic_event_t *event = NULL;
while ((event = xcb_poll_for_event(xnestUpstreamInfo.conn))) {
xnest_handle_event(event);
free(event);
}
xcb_flush(xnestUpstreamInfo.conn);
}

View File

@ -17,12 +17,9 @@ is" without express or implied warranty.
#include <X11/Xmd.h>
#define ProcessedExpose (LASTEvent + 1)
extern CARD32 lastEventTime;
void SetTimeSinceLastInputEvent(void);
void xnestCollectExposures(void);
void xnestCollectEvents(void);
void xnestQueueKeyEvent(int type, unsigned int keycode);

View File

@ -28,7 +28,7 @@ is" without express or implied warranty.
#include "dixfontstr.h"
#include "scrnintstr.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "XNFont.h"
@ -38,7 +38,7 @@ int xnestFontPrivateIndex;
Bool
xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
{
void *priv;
xnestPrivFont *priv;
Atom name_atom, value_atom;
int nprops;
FontPropPtr props;
@ -47,7 +47,7 @@ xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
xfont2_font_set_private(pFont, xnestFontPrivateIndex, NULL);
name_atom = MakeAtom("FONT", 4, True);
name_atom = MakeAtom("FONT", 4, TRUE);
value_atom = 0L;
nprops = pFont->info.nprops;
@ -60,32 +60,46 @@ xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
}
if (!value_atom)
return False;
return FALSE;
name = NameForAtom(value_atom);
if (!name)
return False;
return FALSE;
priv = (void *) malloc(sizeof(xnestPrivFont));
xfont2_font_set_private(pFont, xnestFontPrivateIndex, priv);
xnestFontPriv(pFont)->font_struct = XLoadQueryFont(xnestDisplay, name);
priv->font_id = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_open_font(xnestUpstreamInfo.conn, priv->font_id, strlen(name), name);
if (!xnestFontStruct(pFont))
return False;
xcb_generic_error_t *err = NULL;
priv->font_reply = xcb_query_font_reply(
xnestUpstreamInfo.conn,
xcb_query_font(xnestUpstreamInfo.conn, priv->font_id),
&err);
if (err) {
ErrorF("failed to query font \"%s\": %d", name, err->error_code);
free(err);
return FALSE;
}
if (!priv->font_reply) {
ErrorF("failed to query font \"%s\": no reply", name);
return FALSE;
}
priv->chars_len = xcb_query_font_char_infos_length(priv->font_reply);
priv->chars = xcb_query_font_char_infos(priv->font_reply);
return True;
return TRUE;
}
Bool
xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
{
if (xnestFontPriv(pFont)) {
if (xnestFontStruct(pFont))
XFreeFont(xnestDisplay, xnestFontStruct(pFont));
xcb_close_font(xnestUpstreamInfo.conn, xnestFontPriv(pFont)->font_id);
free(xnestFontPriv(pFont));
xfont2_font_set_private(pFont, xnestFontPrivateIndex, NULL);
}
return True;
return TRUE;
}

View File

@ -28,7 +28,7 @@ is" without express or implied warranty.
#include "mistruct.h"
#include "region.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "XNGC.h"
@ -80,11 +80,14 @@ xnestCreateGC(GCPtr pGC)
pGC->miTranslate = 1;
xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay,
xnestDefaultDrawables[pGC->depth],
0L, NULL);
xnestGCPriv(pGC)->gc = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_gc(xnestUpstreamInfo.conn,
xnestGCPriv(pGC)->gc,
xnestDefaultDrawables[pGC->depth],
0,
NULL);
return True;
return TRUE;
}
void
@ -95,7 +98,7 @@ xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
void
xnestChangeGC(GCPtr pGC, unsigned long mask)
{
XGCValues values;
XnGCValues values;
if (mask & GCFunction)
values.function = pGC->alu;
@ -144,7 +147,7 @@ xnestChangeGC(GCPtr pGC, unsigned long mask)
values.ts_y_origin = pGC->patOrg.y;
if (mask & GCFont)
values.font = xnestFont(pGC->font);
values.font = xnestFontPriv(pGC->font)->font_id;
if (mask & GCSubwindowMode)
values.subwindow_mode = pGC->subWindowMode;
@ -166,62 +169,89 @@ xnestChangeGC(GCPtr pGC, unsigned long mask)
if (mask & GCDashList) {
mask &= ~GCDashList;
XSetDashes(xnestDisplay, xnestGC(pGC),
pGC->dashOffset, (char *) pGC->dash, pGC->numInDashList);
xcb_set_dashes(xnestUpstreamInfo.conn,
xnestUpstreamGC(pGC),
pGC->dashOffset,
pGC->numInDashList,
(uint8_t*) pGC->dash);
}
if (mask & GCArcMode)
values.arc_mode = pGC->arcMode;
if (mask)
XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values);
xnChangeGC(xnestUpstreamInfo.conn, xnestUpstreamGC(pGC), values, mask);
}
void
xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
{
XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst));
xcb_copy_gc(xnestUpstreamInfo.conn,
xnestGC(pGCSrc),
xnestGC(pGCDst),
mask);
}
void
xnestDestroyGC(GCPtr pGC)
{
XFreeGC(xnestDisplay, xnestGC(pGC));
xcb_free_gc(xnestUpstreamInfo.conn, xnestGC(pGC));
}
void
xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
{
int i;
BoxPtr pBox;
XRectangle *pRects;
xnestDestroyClip(pGC);
switch (type) {
case CT_NONE:
XSetClipMask(xnestDisplay, xnestGC(pGC), None);
{
uint32_t pixmap = XCB_PIXMAP_NONE;
xcb_change_gc(xnestUpstreamInfo.conn,
xnestUpstreamGC(pGC),
XCB_GC_CLIP_MASK,
&pixmap);
}
pValue = NULL;
break;
case CT_REGION:
nRects = RegionNumRects((RegionPtr) pValue);
pRects = xallocarray(nRects, sizeof(*pRects));
pBox = RegionRects((RegionPtr) pValue);
for (i = nRects; i-- > 0;) {
pRects[i].x = pBox[i].x1;
pRects[i].y = pBox[i].y1;
pRects[i].width = pBox[i].x2 - pBox[i].x1;
pRects[i].height = pBox[i].y2 - pBox[i].y1;
{
nRects = RegionNumRects((RegionPtr) pValue);
xcb_rectangle_t *rects= calloc(nRects, sizeof(xcb_rectangle_t));
if (rects == NULL) {
ErrorF("xnestChangeClip: memory alloc failure");
return;
}
BoxPtr pBox = RegionRects((RegionPtr) pValue);
for (int i = nRects; i-- > 0;)
rects[i] = (xcb_rectangle_t) {
.x = pBox[i].x1,
.y = pBox[i].y1,
.width = pBox[i].x2 - pBox[i].x1,
.height = pBox[i].y2 - pBox[i].y1,
};
xcb_set_clip_rectangles(
xnestUpstreamInfo.conn,
XCB_CLIP_ORDERING_UNSORTED,
xnestUpstreamGC(pGC),
0,
0,
nRects,
rects);
free(rects);
}
XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0,
pRects, nRects, Unsorted);
free((char *) pRects);
break;
case CT_PIXMAP:
XSetClipMask(xnestDisplay, xnestGC(pGC),
xnestPixmap((PixmapPtr) pValue));
{
uint32_t val = xnestPixmap((PixmapPtr) pValue);
xcb_change_gc(xnestUpstreamInfo.conn,
xnestUpstreamGC(pGC),
XCB_GC_CLIP_MASK,
&val);
}
/*
* Need to change into region, so subsequent uses are with
* current pixmap contents.
@ -232,27 +262,47 @@ xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
break;
case CT_UNSORTED:
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
pGC->clipOrg.x, pGC->clipOrg.y,
(XRectangle *) pValue, nRects, Unsorted);
xcb_set_clip_rectangles(
xnestUpstreamInfo.conn,
XCB_CLIP_ORDERING_UNSORTED,
xnestUpstreamGC(pGC),
pGC->clipOrg.x, pGC->clipOrg.y,
nRects,
(xcb_rectangle_t*)pValue);
break;
case CT_YSORTED:
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
pGC->clipOrg.x, pGC->clipOrg.y,
(XRectangle *) pValue, nRects, YSorted);
xcb_set_clip_rectangles(
xnestUpstreamInfo.conn,
XCB_CLIP_ORDERING_Y_SORTED,
xnestUpstreamGC(pGC),
pGC->clipOrg.x,
pGC->clipOrg.y,
nRects,
(xcb_rectangle_t*)pValue);
break;
case CT_YXSORTED:
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
pGC->clipOrg.x, pGC->clipOrg.y,
(XRectangle *) pValue, nRects, YXSorted);
xcb_set_clip_rectangles(
xnestUpstreamInfo.conn,
XCB_CLIP_ORDERING_YX_SORTED,
xnestUpstreamGC(pGC),
pGC->clipOrg.x,
pGC->clipOrg.y,
nRects,
(xcb_rectangle_t*)pValue);
break;
case CT_YXBANDED:
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
pGC->clipOrg.x, pGC->clipOrg.y,
(XRectangle *) pValue, nRects, YXBanded);
xcb_set_clip_rectangles(
xnestUpstreamInfo.conn,
XCB_CLIP_ORDERING_YX_BANDED,
xnestUpstreamGC(pGC),
pGC->clipOrg.x,
pGC->clipOrg.y,
nRects,
(xcb_rectangle_t*)pValue);
break;
}
@ -279,7 +329,11 @@ xnestDestroyClip(GCPtr pGC)
{
if (pGC->clientClip) {
RegionDestroy(pGC->clientClip);
XSetClipMask(xnestDisplay, xnestGC(pGC), None);
uint32_t val = XCB_PIXMAP_NONE;
xcb_change_gc(xnestUpstreamInfo.conn,
xnestUpstreamGC(pGC),
XCB_GC_CLIP_MASK,
&val);
pGC->clientClip = NULL;
}
}

View File

@ -29,7 +29,7 @@ is" without express or implied warranty.
#include "region.h"
#include "servermd.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Screen.h"
@ -37,7 +37,6 @@ is" without express or implied warranty.
#include "XNFont.h"
#include "GCOps.h"
#include "Drawable.h"
#include "Visual.h"
void
xnestFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans, xPoint * pPoints,
@ -64,74 +63,81 @@ void
xnestQueryBestSize(int class, unsigned short *pWidth, unsigned short *pHeight,
ScreenPtr pScreen)
{
unsigned int width, height;
xcb_generic_error_t *err = NULL;
xcb_query_best_size_reply_t *reply = xcb_query_best_size_reply(
xnestUpstreamInfo.conn,
xcb_query_best_size(
xnestUpstreamInfo.conn,
class,
xnestDefaultWindows[pScreen->myNum],
*pWidth,
*pHeight),
&err);
width = *pWidth;
height = *pHeight;
if (err) {
ErrorF("QueryBestSize request failed: %d\n", err->error_code);
free(err);
return;
}
XQueryBestSize(xnestDisplay, class,
xnestDefaultWindows[pScreen->myNum],
width, height, &width, &height);
if (!reply) {
ErrorF("QueryBestSize request failed: no reply\n");
return;
}
*pWidth = width;
*pHeight = height;
*pWidth = reply->width;
*pHeight = reply->height;
free(reply);
}
void
xnestPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int w, int h, int leftPad, int format, char *pImage)
{
XImage *ximage;
ximage = XCreateImage(xnestDisplay, xnestDefaultVisual(pDrawable->pScreen),
depth, format, leftPad, (char *) pImage,
w, h, BitmapPad(xnestDisplay),
(format == ZPixmap) ?
PixmapBytePad(w, depth) : BitmapBytePad(w + leftPad));
if (ximage) {
XPutImage(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
ximage, 0, 0, x, y, w, h);
XFree(ximage);
}
}
static int
xnestIgnoreErrorHandler (Display *dpy,
XErrorEvent *event)
{
return False; /* return value is ignored */
xcb_put_image(xnestUpstreamInfo.conn,
format,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
w,
h,
x,
y,
leftPad,
depth,
(format == XCB_IMAGE_FORMAT_Z_PIXMAP ? PixmapBytePad(w, depth)
: BitmapBytePad(w + leftPad)) * h,
(uint8_t*)pImage);
}
void
xnestGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *pImage)
{
XImage *ximage;
int length;
int (*old_handler)(Display*, XErrorEvent*);
xcb_generic_error_t * err = NULL;
xcb_get_image_reply_t *reply= xcb_get_image_reply(
xnestUpstreamInfo.conn,
xcb_get_image(
xnestUpstreamInfo.conn,
format,
xnestDrawable(pDrawable),
x, y, w, h, planeMask),
&err);
/* we may get BadMatch error when xnest window is minimized */
XSync(xnestDisplay, False);
old_handler = XSetErrorHandler (xnestIgnoreErrorHandler);
ximage = XGetImage(xnestDisplay, xnestDrawable(pDrawable),
x, y, w, h, planeMask, format);
XSetErrorHandler(old_handler);
if (ximage) {
length = ximage->bytes_per_line * ximage->height;
memmove(pImage, ximage->data, length);
XDestroyImage(ximage);
if (err) {
// badMatch may happeen if the upstream window is currently minimized
if (err->error_code != BadMatch)
LogMessage(X_WARNING, "xnestGetImage: received error %d\n", err->error_code);
free(err);
return;
}
}
static Bool
xnestBitBlitPredicate(Display * dpy, XEvent * event, char *args)
{
return event->type == GraphicsExpose || event->type == NoExpose;
if (!reply) {
LogMessage(X_WARNING, "xnestGetImage: received no reply\n");
return;
}
memmove(pImage, xcb_get_image_data(reply), xcb_get_image_data_length(reply));
free(reply);
}
static RegionPtr
@ -140,9 +146,7 @@ xnestBitBlitHelper(GCPtr pGC)
if (!pGC->graphicsExposures)
return NullRegion;
else {
XEvent event;
RegionPtr pReg, pTmpReg;
BoxRec Box;
Bool pending, overlap;
pReg = RegionCreate(NULL, 1);
@ -150,24 +154,43 @@ xnestBitBlitHelper(GCPtr pGC)
if (!pReg || !pTmpReg)
return NullRegion;
pending = True;
xcb_flush(xnestUpstreamInfo.conn);
pending = TRUE;
while (pending) {
XIfEvent(xnestDisplay, &event, xnestBitBlitPredicate, NULL);
switch (event.type) {
case NoExpose:
pending = False;
xcb_generic_event_t *event = xcb_wait_for_event(xnestUpstreamInfo.conn);
if (!event) {
pending = FALSE;
break;
}
case GraphicsExpose:
Box.x1 = event.xgraphicsexpose.x;
Box.y1 = event.xgraphicsexpose.y;
Box.x2 = event.xgraphicsexpose.x + event.xgraphicsexpose.width;
Box.y2 = event.xgraphicsexpose.y + event.xgraphicsexpose.height;
RegionReset(pTmpReg, &Box);
RegionAppend(pReg, pTmpReg);
pending = event.xgraphicsexpose.count;
break;
switch (event->response_type & ~0x80) {
case NoExpose:
pending = FALSE;
free(event);
break;
case GraphicsExpose:
{
xcb_graphics_exposure_event_t* ev = (xcb_graphics_exposure_event_t*)event;
BoxRec Box = {
.x1 = ev->x,
.y1 = ev->y,
.x2 = ev->x + ev->width,
.y2 = ev->y + ev->height,
};
RegionReset(pTmpReg, &Box);
RegionAppend(pReg, pTmpReg);
pending = ev->count;
free(event);
break;
}
default:
{
xnestEventQueue *q = malloc(sizeof(xnestEventQueue));
q->event = event;
xorg_list_add(&q->entry, &xnestUpstreamInfo.eventQueue.entry);
}
}
}
@ -182,9 +205,11 @@ xnestCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
GCPtr pGC, int srcx, int srcy, int width, int height,
int dstx, int dsty)
{
XCopyArea(xnestDisplay,
xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
xnestGC(pGC), srcx, srcy, width, height, dstx, dsty);
xcb_copy_area(xnestUpstreamInfo.conn,
xnestDrawable(pSrcDrawable),
xnestDrawable(pDstDrawable),
xnestUpstreamGC(pGC),
srcx, srcy, dstx, dsty, width, height);
return xnestBitBlitHelper(pGC);
}
@ -194,9 +219,11 @@ xnestCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
GCPtr pGC, int srcx, int srcy, int width, int height,
int dstx, int dsty, unsigned long plane)
{
XCopyPlane(xnestDisplay,
xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
xnestGC(pGC), srcx, srcy, width, height, dstx, dsty, plane);
xcb_copy_plane(xnestUpstreamInfo.conn,
xnestDrawable(pSrcDrawable),
xnestDrawable(pDstDrawable),
xnestUpstreamGC(pGC),
srcx, srcy, dstx, dsty, width, height, plane);
return xnestBitBlitHelper(pGC);
}
@ -205,106 +232,184 @@ void
xnestPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
DDXPointPtr pPoints)
{
XDrawPoints(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
(XPoint *) pPoints, nPoints, mode);
/* xPoint and xcb_segment_t are defined in the same way, both matching
the protocol layout, so we can directly typecast them */
xcb_poly_point(xnestUpstreamInfo.conn,
mode,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
nPoints,
(xcb_point_t*)pPoints);
}
void
xnestPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
DDXPointPtr pPoints)
{
XDrawLines(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
(XPoint *) pPoints, nPoints, mode);
/* xPoint and xcb_segment_t are defined in the same way, both matching
the protocol layout, so we can directly typecast them */
xcb_poly_line(xnestUpstreamInfo.conn,
mode,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
nPoints,
(xcb_point_t*)pPoints);
}
void
xnestPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments,
xSegment * pSegments)
{
XDrawSegments(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
(XSegment *) pSegments, nSegments);
/* xSegment and xcb_segment_t are defined in the same way, both matching
the protocol layout, so we can directly typecast them */
xcb_poly_segment(xnestUpstreamInfo.conn,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
nSegments,
(xcb_segment_t*)pSegments);
}
void
xnestPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
xRectangle *pRectangles)
{
XDrawRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
(XRectangle *) pRectangles, nRectangles);
/* xRectangle and xcb_rectangle_t are defined in the same way, both matching
the protocol layout, so we can directly typecast them */
xcb_poly_rectangle(xnestUpstreamInfo.conn,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
nRectangles,
(xcb_rectangle_t*)pRectangles);
}
void
xnestPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
{
XDrawArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
(XArc *) pArcs, nArcs);
/* xArc and xcb_arc_t are defined in the same way, both matching
the protocol layout, so we can directly typecast them */
xcb_poly_arc(xnestUpstreamInfo.conn,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
nArcs,
(xcb_arc_t*)pArcs);
}
void
xnestFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode,
int nPoints, DDXPointPtr pPoints)
{
XFillPolygon(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
(XPoint *) pPoints, nPoints, shape, mode);
/* xPoint and xcb_segment_t are defined in the same way, both matching
the protocol layout, so we can directly typecast them */
xcb_fill_poly(xnestUpstreamInfo.conn,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
shape,
mode,
nPoints,
(xcb_point_t*)pPoints);
}
void
xnestPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
xRectangle *pRectangles)
{
XFillRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
(XRectangle *) pRectangles, nRectangles);
/* xRectangle and xcb_rectangle_t are defined in the same way, both matching
the protocol layout, so we can directly typecast them */
xcb_poly_fill_rectangle(xnestUpstreamInfo.conn,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
nRectangles,
(xcb_rectangle_t*)pRectangles);
}
void
xnestPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
{
XFillArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
(XArc *) pArcs, nArcs);
/* xArc and xcb_arc_t are defined in the same way, both matching
the protocol layout, so we can directly typecast them */
xcb_poly_fill_arc(xnestUpstreamInfo.conn,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
nArcs,
(xcb_arc_t*)pArcs);
}
int
xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
char *string)
{
int width;
// we need to prepend a xTextElt struct before our actual characters
// won't get more than 254 elements, since it's already processed by doPolyText()
int const bufsize = sizeof(xTextElt) + count;
uint8_t *buffer = malloc(bufsize);
xTextElt *elt = (xTextElt*)buffer;
elt->len = count;
elt->delta = 0;
memcpy(buffer+2, string, count);
XDrawString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
x, y, string, count);
xcb_poly_text_8(xnestUpstreamInfo.conn,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
x,
y,
bufsize,
(uint8_t*)buffer);
width = XTextWidth(xnestFontStruct(pGC->font), string, count);
free(buffer);
return width + x;
return x + xnestTextWidth(xnestFontPriv(pGC->font), string, count);
}
int
xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
unsigned short *string)
{
int width;
// we need to prepend a xTextElt struct before our actual characters
// won't get more than 254 elements, since it's already processed by doPolyText()
int const bufsize = sizeof(xTextElt) + count*2;
uint8_t *buffer = malloc(bufsize);
xTextElt *elt = (xTextElt*)buffer;
elt->len = count;
elt->delta = 0;
memcpy(buffer+2, string, count*2);
XDrawString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
x, y, (XChar2b *) string, count);
xcb_poly_text_16(xnestUpstreamInfo.conn,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
x,
y,
bufsize,
buffer);
width = XTextWidth16(xnestFontStruct(pGC->font), (XChar2b *) string, count);
free(buffer);
return width + x;
return x + xnestTextWidth16(xnestFontPriv(pGC->font), string, count);
}
void
xnestImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
char *string)
{
XDrawImageString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
x, y, string, count);
xcb_image_text_8(xnestUpstreamInfo.conn,
count,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
x,
y,
string);
}
void
xnestImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
unsigned short *string)
{
XDrawImageString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
x, y, (XChar2b *) string, count);
xcb_image_text_16(xnestUpstreamInfo.conn,
count,
xnestDrawable(pDrawable),
xnestUpstreamGC(pGC),
x,
y,
(xcb_char2b_t*)string);
}
void
@ -329,12 +434,35 @@ xnestPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDst,
{
/* only works for solid bitmaps */
if (pGC->fillStyle == FillSolid) {
XSetStipple(xnestDisplay, xnestGC(pGC), xnestPixmap(pBitmap));
XSetTSOrigin(xnestDisplay, xnestGC(pGC), x, y);
XSetFillStyle(xnestDisplay, xnestGC(pGC), FillStippled);
XFillRectangle(xnestDisplay, xnestDrawable(pDst),
xnestGC(pGC), x, y, width, height);
XSetFillStyle(xnestDisplay, xnestGC(pGC), FillSolid);
xnChangeGC(xnestUpstreamInfo.conn,
xnestUpstreamGC(pGC),
(XnGCValues) {
.fill_style = XCB_FILL_STYLE_STIPPLED,
.ts_x_origin = x,
.ts_y_origin = y,
.stipple = xnestPixmap(pBitmap),
},
XCB_GC_FILL_STYLE | XCB_GC_TILE_STIPPLE_ORIGIN_X |
XCB_GC_TILE_STIPPLE_ORIGIN_Y | XCB_GC_STIPPLE);
xcb_rectangle_t rect = {
.x = x, .y = y, .width = width, .height = height,
};
xcb_poly_fill_rectangle(xnestUpstreamInfo.conn,
xnestDrawable(pDst),
xnestUpstreamGC(pGC),
1,
&rect);
xnChangeGC(xnestUpstreamInfo.conn,
xnestUpstreamGC(pGC),
(XnGCValues) {
.fill_style = XCB_FILL_STYLE_SOLID,
.ts_x_origin = x,
.ts_y_origin = y,
.stipple = xnestPixmap(pBitmap),
},
XCB_GC_FILL_STYLE);
}
else
ErrorF("xnest warning: function xnestPushPixels not implemented\n");

View File

@ -25,8 +25,6 @@ is" without express or implied warranty.
#include "windowstr.h"
#include "servermd.h"
#include "Xnest.h"
#include "Display.h"
#include "Events.h"
#include "Handlers.h"
@ -34,8 +32,7 @@ is" without express or implied warranty.
void
xnestBlockHandler(void *blockData, void *timeout)
{
xnestCollectExposures();
XFlush(xnestDisplay);
xnestCollectEvents();
}
void

View File

@ -34,8 +34,8 @@ is" without express or implied warranty.
#include "mi.h"
#include "dixfontstr.h"
#include "extinit_priv.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Screen.h"
#include "Pointer.h"
@ -51,7 +51,7 @@ is" without express or implied warranty.
#include "dpmsproc.h"
#endif
Bool xnestDoFullGeneration = True;
Bool xnestDoFullGeneration = TRUE;
#ifdef GLXEXT
void
@ -63,29 +63,37 @@ GlxExtensionInit(void)
void
InitOutput(ScreenInfo * screen_info, int argc, char *argv[])
{
int i, j;
int i;
xnestOpenDisplay(argc, argv);
screen_info->imageByteOrder = ImageByteOrder(xnestDisplay);
screen_info->bitmapScanlineUnit = BitmapUnit(xnestDisplay);
screen_info->bitmapScanlinePad = BitmapPad(xnestDisplay);
screen_info->bitmapBitOrder = BitmapBitOrder(xnestDisplay);
screen_info->imageByteOrder = xnestUpstreamInfo.setup->image_byte_order;
screen_info->bitmapScanlineUnit = xnestUpstreamInfo.setup->bitmap_format_scanline_unit;
screen_info->bitmapScanlinePad = xnestUpstreamInfo.setup->bitmap_format_scanline_pad;
screen_info->bitmapBitOrder = xnestUpstreamInfo.setup->bitmap_format_bit_order;
screen_info->numPixmapFormats = 0;
for (i = 0; i < xnestNumPixmapFormats; i++)
for (j = 0; j < xnestNumDepths; j++)
if ((xnestPixmapFormats[i].depth == 1) ||
(xnestPixmapFormats[i].depth == xnestDepths[j])) {
xcb_format_t *fmt = xcb_setup_pixmap_formats(xnestUpstreamInfo.setup);
const xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(xnestUpstreamInfo.setup);
for(; fmt != fmtend; ++fmt) {
xcb_depth_iterator_t depth_iter;
for (depth_iter = xcb_screen_allowed_depths_iterator(xnestUpstreamInfo.screenInfo);
depth_iter.rem;
xcb_depth_next(&depth_iter))
{
if ((fmt->depth == 1) ||
(fmt->depth == depth_iter.data->depth)) {
screen_info->formats[screen_info->numPixmapFormats].depth =
xnestPixmapFormats[i].depth;
fmt->depth;
screen_info->formats[screen_info->numPixmapFormats].bitsPerPixel =
xnestPixmapFormats[i].bits_per_pixel;
fmt->bits_per_pixel;
screen_info->formats[screen_info->numPixmapFormats].scanlinePad =
xnestPixmapFormats[i].scanline_pad;
fmt->scanline_pad;
screen_info->numPixmapFormats++;
break;
}
}
}
xnestFontPrivateIndex = xfont2_allocate_font_private_index();
@ -121,7 +129,10 @@ InitInput(int argc, char *argv[])
mieqInit();
SetNotifyFd(XConnectionNumber(xnestDisplay), xnestNotifyConnection, X_NOTIFY_READ, NULL);
SetNotifyFd(xcb_get_file_descriptor(xnestUpstreamInfo.conn),
xnestNotifyConnection,
X_NOTIFY_READ,
NULL);
RegisterBlockAndWakeupHandlers(xnestBlockHandler, xnestWakeupHandler, NULL);
}
@ -135,7 +146,7 @@ CloseInput(void)
void
ddxGiveUp(enum ExitCode error)
{
xnestDoFullGeneration = True;
xnestDoFullGeneration = TRUE;
xnestCloseDisplay();
}

View File

@ -24,6 +24,7 @@ is" without express or implied warranty.
#include <X11/Xdefs.h>
#include <X11/Xproto.h>
#include <X11/keysym.h>
#include <xcb/xkb.h>
#include "screenint.h"
#include "inputstr.h"
@ -31,7 +32,7 @@ is" without express or implied warranty.
#include "scrnintstr.h"
#include "servermd.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Screen.h"
@ -41,39 +42,19 @@ is" without express or implied warranty.
#include <X11/extensions/XKB.h>
#include "xkbsrv.h"
#include <X11/extensions/XKBconfig.h>
extern Bool
XkbQueryExtension(Display * /* dpy */ ,
int * /* opcodeReturn */ ,
int * /* eventBaseReturn */ ,
int * /* errorBaseReturn */ ,
int * /* majorRtrn */ ,
int * /* minorRtrn */
);
extern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ ,
unsigned int /* which */ ,
unsigned int /* deviceSpec */
);
extern Status XkbGetControls(Display * /* dpy */ ,
unsigned long /* which */ ,
XkbDescPtr /* desc */
);
DeviceIntPtr xnestKeyboardDevice = NULL;
void
xnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls)
{
XBell(xnestDisplay, volume);
xcb_bell(xnestUpstreamInfo.conn, volume);
}
void
DDXRingBell(int volume, int pitch, int duration)
{
XBell(xnestDisplay, volume);
xcb_bell(xnestUpstreamInfo.conn, volume);
}
void
@ -81,7 +62,7 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
{
#if 0
unsigned long value_mask;
XKeyboardControl values;
XnKeyboardControl values;
int i;
value_mask = KBKeyClickPercent |
@ -94,7 +75,9 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
values.auto_repeat_mode = ctrl->autoRepeat ?
AutoRepeatModeOn : AutoRepeatModeOff;
XChangeKeyboardControl(xnestDisplay, value_mask, &values);
uint32_t value_list[16];
xnestEncodeKeyboardControl(values, value_mask, value_list);
xcb_change_keyboard_control(xnestUpstreamConn(), value_mask, value_list);
/*
value_mask = KBKey | KBAutoRepeatMode;
@ -107,7 +90,9 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
values.led = i;
values.led_mode =
(ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
XChangeKeyboardControl(xnestDisplay, value_mask, &values);
xnestEncodeKeyboardControl(values, value_mask, value_list);
xcb_change_keyboard_control(xnestUpstreamConn(), value_mask, value_list);
}
#endif
}
@ -115,73 +100,60 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
int
xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
{
XModifierKeymap *modifier_keymap;
KeySym *keymap;
int mapWidth;
int min_keycode, max_keycode;
KeySymsRec keySyms;
CARD8 modmap[MAP_LENGTH];
int i, j;
XKeyboardState values;
XkbDescPtr xkb;
int op, event, error, major, minor;
switch (onoff) {
case DEVICE_INIT:
XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
#ifdef _XSERVER64
{
KeySym64 *keymap64;
int len;
{
const int min_keycode = xnestUpstreamInfo.setup->min_keycode;
const int max_keycode = xnestUpstreamInfo.setup->max_keycode;
const int num_keycode = max_keycode - min_keycode + 1;
keymap64 = XGetKeyboardMapping(xnestDisplay,
min_keycode,
max_keycode - min_keycode + 1,
&mapWidth);
len = (max_keycode - min_keycode + 1) * mapWidth;
keymap = xallocarray(len, sizeof(KeySym));
for (i = 0; i < len; ++i)
keymap[i] = keymap64[i];
XFree(keymap64);
xcb_get_keyboard_mapping_reply_t * keymap_reply = xnestGetKeyboardMapping(
xnestUpstreamInfo.conn,
min_keycode,
num_keycode);
if (!keymap_reply) {
ErrorF("Couldn't get keyboard mappings: no reply");
goto XkbError;
}
#else
keymap = XGetKeyboardMapping(xnestDisplay,
min_keycode,
max_keycode - min_keycode + 1, &mapWidth);
#endif
memset(modmap, 0, sizeof(modmap));
modifier_keymap = XGetModifierMapping(xnestDisplay);
KeySymsRec keySyms = {
.minKeyCode = min_keycode,
.maxKeyCode = max_keycode,
.mapWidth = keymap_reply->keysyms_per_keycode,
.map = xcb_get_keyboard_mapping_keysyms(keymap_reply),
};
xcb_generic_error_t *mod_err = NULL;
xcb_get_modifier_mapping_reply_t *mod_reply = xcb_get_modifier_mapping_reply(
xnestUpstreamInfo.conn,
xcb_get_modifier_mapping(xnestUpstreamInfo.conn),
&mod_err);
if (mod_err) {
free(keymap_reply);
ErrorF("Couldn't get keyboard modifier mapping: %d\n", mod_err->error_code);
goto XkbError;
}
if (!mod_reply) {
free(keymap_reply);
ErrorF("Couldn't get keyboard modifier mapping: no reply\n");
goto XkbError;
}
xcb_keycode_t *mod_keycodes = xcb_get_modifier_mapping_keycodes(mod_reply);
CARD8 modmap[MAP_LENGTH] = { 0 };
for (j = 0; j < 8; j++)
for (i = 0; i < modifier_keymap->max_keypermod; i++) {
for (i = 0; i < mod_reply->keycodes_per_modifier; i++) {
CARD8 keycode;
if ((keycode =
modifier_keymap->modifiermap[j *
modifier_keymap->
max_keypermod + i]))
mod_keycodes[j * mod_reply->keycodes_per_modifier + i]))
modmap[keycode] |= 1 << j;
}
XFreeModifiermap(modifier_keymap);
keySyms.minKeyCode = min_keycode;
keySyms.maxKeyCode = max_keycode;
keySyms.mapWidth = mapWidth;
keySyms.map = keymap;
if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor)
== 0) {
ErrorF("Unable to initialize XKEYBOARD extension.\n");
goto XkbError;
}
xkb =
XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask,
XkbUseCoreKbd);
if (xkb == NULL || xkb->geom == NULL) {
ErrorF("Couldn't get keyboard.\n");
goto XkbError;
}
XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
InitKeyboardDeviceStruct(pDev, NULL,
xnestBell, xnestChangeKeyboardControl);
@ -190,32 +162,109 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
keySyms.maxKeyCode - keySyms.minKeyCode + 1,
modmap, serverClient);
XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
XkbFreeKeyboard(xkb, 0, False);
free(keymap);
free(keymap_reply);
xnestXkbInit(xnestUpstreamInfo.conn);
int device_id = xnestXkbDeviceId(xnestUpstreamInfo.conn);
xcb_generic_error_t *err = NULL;
xcb_xkb_get_controls_reply_t *reply = xcb_xkb_get_controls_reply(
xnestUpstreamInfo.conn,
xcb_xkb_get_controls(xnestUpstreamInfo.conn, device_id),
&err);
if (err) {
ErrorF("Couldn't get keyboard controls for %d: error %d\n", device_id, err->error_code);
free(err);
goto XkbError;
}
if (!reply) {
ErrorF("Couldn't get keyboard controls for %d: no reply", device_id);
goto XkbError;
}
XkbControlsRec ctrls = {
.mk_dflt_btn = reply->mouseKeysDfltBtn,
.num_groups = reply->numGroups,
.groups_wrap = reply->groupsWrap,
.internal = (XkbModsRec) {
.mask = reply->internalModsMask,
.real_mods = reply->internalModsRealMods,
.vmods = reply->internalModsVmods,
},
.ignore_lock = (XkbModsRec) {
.mask = reply->ignoreLockModsMask,
.real_mods = reply->ignoreLockModsRealMods,
.vmods = reply->ignoreLockModsVmods,
},
.enabled_ctrls = reply->enabledControls,
.repeat_delay = reply->repeatDelay,
.repeat_interval = reply->repeatInterval,
.slow_keys_delay = reply->slowKeysDelay,
.debounce_delay = reply->debounceDelay,
.mk_delay = reply->mouseKeysDelay,
.mk_interval = reply->mouseKeysInterval,
.mk_time_to_max = reply->mouseKeysTimeToMax,
.mk_max_speed = reply->mouseKeysMaxSpeed,
.mk_curve = reply->mouseKeysCurve,
.ax_options = reply->accessXOption,
.ax_timeout = reply->accessXTimeout,
.axt_opts_mask = reply->accessXTimeoutOptionsMask,
.axt_opts_values = reply->accessXTimeoutOptionsValues,
.axt_ctrls_mask = reply->accessXTimeoutMask,
.axt_ctrls_values = reply->accessXTimeoutValues,
};
memcpy(&ctrls.per_key_repeat, reply->perKeyRepeat, sizeof(ctrls.per_key_repeat));
XkbDDXChangeControls(pDev, &ctrls, &ctrls);
break;
}
case DEVICE_ON:
xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
for (i = 0; i < xnestNumScreens; i++)
XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
xcb_change_window_attributes(xnestUpstreamInfo.conn,
xnestDefaultWindows[i],
XCB_CW_EVENT_MASK,
&xnestEventMask);
break;
case DEVICE_OFF:
xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
for (i = 0; i < xnestNumScreens; i++)
XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
xcb_change_window_attributes(xnestUpstreamInfo.conn,
xnestDefaultWindows[i],
XCB_CW_EVENT_MASK,
&xnestEventMask);
break;
case DEVICE_CLOSE:
break;
}
return Success;
XkbError:
XGetKeyboardControl(xnestDisplay, &values);
memmove((char *) defaultKeyboardControl.autoRepeats,
(char *) values.auto_repeats, sizeof(values.auto_repeats));
XkbError:
{
xcb_generic_error_t *ctrl_err = NULL;
xcb_get_keyboard_control_reply_t *ctrl_reply =
xcb_get_keyboard_control_reply(xnestUpstreamInfo.conn,
xcb_get_keyboard_control(xnestUpstreamInfo.conn),
&ctrl_err);
if (ctrl_err) {
ErrorF("failed retrieving keyboard control: %d\n", ctrl_err->error_code);
free(ctrl_err);
}
else if (!ctrl_reply) {
ErrorF("failed retrieving keyboard control: no reply\n");
}
else {
memcpy(defaultKeyboardControl.autoRepeats,
ctrl_reply->auto_repeats,
sizeof(ctrl_reply->auto_repeats));
free(ctrl_reply);
}
}
InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl);
free(keymap);
return Success;
}

View File

@ -16,7 +16,8 @@ is" without express or implied warranty.
#define XNESTKEYBOARD_H
#define XNEST_KEYBOARD_EVENT_MASK \
(KeyPressMask | KeyReleaseMask | FocusChangeMask | KeymapStateMask)
(XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | \
XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_KEYMAP_STATE)
extern DeviceIntPtr xnestKeyboardDevice;

View File

@ -28,7 +28,7 @@ is" without express or implied warranty.
#include "privates.h"
#include "mi.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Screen.h"
@ -59,11 +59,12 @@ xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
pPixmap->refcnt = 1;
pPixmap->devKind = PixmapBytePad(width, depth);
pPixmap->usage_hint = usage_hint;
if (width && height)
xnestPixmapPriv(pPixmap)->pixmap =
XCreatePixmap(xnestDisplay,
xnestDefaultWindows[pScreen->myNum],
width, height, depth);
if (width && height) {
uint32_t pixmap = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_pixmap(xnestUpstreamInfo.conn, depth, pixmap,
xnestDefaultWindows[pScreen->myNum], width, height);
xnestPixmapPriv(pPixmap)->pixmap = pixmap;
}
else
xnestPixmapPriv(pPixmap)->pixmap = 0;
@ -75,7 +76,7 @@ xnestDestroyPixmap(PixmapPtr pPixmap)
{
if (--pPixmap->refcnt)
return TRUE;
XFreePixmap(xnestDisplay, xnestPixmap(pPixmap));
xcb_free_pixmap(xnestUpstreamInfo.conn, xnestPixmap(pPixmap));
FreePixmap(pPixmap);
return TRUE;
}
@ -85,10 +86,11 @@ xnestModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
int bitsPerPixel, int devKind, void *pPixData)
{
if(!xnestPixmapPriv(pPixmap)->pixmap && width > 0 && height > 0) {
xnestPixmapPriv(pPixmap)->pixmap =
XCreatePixmap(xnestDisplay,
xnestDefaultWindows[pPixmap->drawable.pScreen->myNum],
width, height, depth);
uint32_t pixmap = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_pixmap(xnestUpstreamInfo.conn, depth, pixmap,
xnestDefaultWindows[pPixmap->drawable.pScreen->myNum],
width, height);
xnestPixmapPriv(pPixmap)->pixmap = pixmap;
}
return miModifyPixmapHeader(pPixmap, width, height, depth,
@ -98,30 +100,60 @@ xnestModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
RegionPtr
xnestPixmapToRegion(PixmapPtr pPixmap)
{
XImage *ximage;
register RegionPtr pReg, pTmpReg;
register int x, y;
unsigned long previousPixel, currentPixel;
BoxRec Box = { 0, 0, 0, 0 };
Bool overlap;
ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0,
pPixmap->drawable.width, pPixmap->drawable.height,
1, XYPixmap);
if (pPixmap->drawable.depth != 1) {
LogMessage(X_WARNING, "xnestPixmapToRegion() depth != 1: %d\n", pPixmap->drawable.depth);
return NULL;
}
xcb_generic_error_t *err = NULL;
xcb_get_image_reply_t *reply = xcb_get_image_reply(
xnestUpstreamInfo.conn,
xcb_get_image(
xnestUpstreamInfo.conn,
XCB_IMAGE_FORMAT_XY_PIXMAP,
xnestPixmap(pPixmap),
0,
0,
pPixmap->drawable.width,
pPixmap->drawable.height,
~0),
&err);
if (err) {
// badMatch may happeen if the upstream window is currently minimized
if (err->error_code != BadMatch)
ErrorF("xnestGetImage: received error %d\n", err->error_code);
free(err);
return NULL;
}
if (!reply) {
ErrorF("xnestGetImage: received no reply\n");
return NULL;
}
pReg = RegionCreate(NULL, 1);
pTmpReg = RegionCreate(NULL, 1);
if (!pReg || !pTmpReg) {
XDestroyImage(ximage);
free(reply);
return NullRegion;
}
uint8_t *image_data = xcb_get_image_data(reply);
for (y = 0; y < pPixmap->drawable.height; y++) {
Box.y1 = y;
Box.y2 = y + 1;
previousPixel = 0L;
const int line_start = BitmapBytePad(pPixmap->drawable.width) * y;
for (x = 0; x < pPixmap->drawable.width; x++) {
currentPixel = XGetPixel(ximage, x, y);
currentPixel = ((image_data[line_start + (x/8)]) >> (x % 8)) & 1;
if (previousPixel != currentPixel) {
if (previousPixel == 0L) {
/* left edge */
@ -145,7 +177,7 @@ xnestPixmapToRegion(PixmapPtr pPixmap)
}
RegionDestroy(pTmpReg);
XDestroyImage(ximage);
free(reply);
RegionValidate(pReg, &overlap);

View File

@ -26,7 +26,7 @@ is" without express or implied warranty.
#include "servermd.h"
#include "mipointer.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Screen.h"
@ -41,25 +41,24 @@ DeviceIntPtr xnestPointerDevice = NULL;
void
xnestChangePointerControl(DeviceIntPtr pDev, PtrCtrl * ctrl)
{
XChangePointerControl(xnestDisplay, True, True,
ctrl->num, ctrl->den, ctrl->threshold);
xcb_change_pointer_control(xnestUpstreamInfo.conn,
ctrl->num,
ctrl->den,
ctrl->threshold,
TRUE,
TRUE);
}
int
xnestPointerProc(DeviceIntPtr pDev, int onoff)
{
CARD8 map[MAXBUTTONS];
Atom btn_labels[MAXBUTTONS] = { 0 };
Atom axes_labels[2] = { 0 };
int nmap;
int i;
switch (onoff) {
case DEVICE_INIT:
nmap = XGetPointerMapping(xnestDisplay, map, MAXBUTTONS);
for (i = 0; i <= nmap; i++)
map[i] = i; /* buttons are already mapped */
{
btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
@ -71,23 +70,57 @@ xnestPointerProc(DeviceIntPtr pDev, int onoff)
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
XGetPointerControl(xnestDisplay,
&defaultPointerControl.num,
&defaultPointerControl.den,
&defaultPointerControl.threshold);
InitPointerDeviceStruct(&pDev->public, map, nmap, btn_labels,
xnestGetPointerControl(xnestUpstreamInfo.conn,
&defaultPointerControl.num,
&defaultPointerControl.den,
&defaultPointerControl.threshold);
xcb_generic_error_t *pm_err = NULL;
xcb_get_pointer_mapping_reply_t *pm_reply =
xcb_get_pointer_mapping_reply(
xnestUpstreamInfo.conn,
xcb_get_pointer_mapping(xnestUpstreamInfo.conn),
&pm_err);
if (pm_err) {
ErrorF("failed getting pointer mapping %d\n", pm_err->error_code);
free(pm_err);
break;
}
if (!pm_reply) {
ErrorF("failed getting pointer mapping: no reply\n");
break;
}
const int nmap = xcb_get_pointer_mapping_map_length(pm_reply);
uint8_t *map = xcb_get_pointer_mapping_map(pm_reply);
for (i=0; i<nmap; i++)
map[i] = i; /* buttons are already mapped */
InitPointerDeviceStruct(&pDev->public,
map,
nmap,
btn_labels,
xnestChangePointerControl,
GetMotionHistorySize(), 2, axes_labels);
free(pm_reply);
break;
}
case DEVICE_ON:
xnestEventMask |= XNEST_POINTER_EVENT_MASK;
for (i = 0; i < xnestNumScreens; i++)
XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
xcb_change_window_attributes(xnestUpstreamInfo.conn,
xnestDefaultWindows[i],
XCB_CW_EVENT_MASK,
&xnestEventMask);
break;
case DEVICE_OFF:
xnestEventMask &= ~XNEST_POINTER_EVENT_MASK;
for (i = 0; i < xnestNumScreens; i++)
XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
xcb_change_window_attributes(xnestUpstreamInfo.conn,
xnestDefaultWindows[i],
XCB_CW_EVENT_MASK,
&xnestEventMask);
break;
case DEVICE_CLOSE:
break;

View File

@ -20,6 +20,8 @@ is" without express or implied warranty.
#include <X11/Xdefs.h>
#include <X11/Xproto.h>
#include <xcb/xcb_icccm.h>
#include "mi/mi_priv.h"
#include "scrnintstr.h"
@ -29,7 +31,7 @@ is" without express or implied warranty.
#include "colormapst.h"
#include "resource.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Screen.h"
@ -39,7 +41,6 @@ is" without express or implied warranty.
#include "XNFont.h"
#include "Color.h"
#include "XNCursor.h"
#include "Visual.h"
#include "Events.h"
#include "Init.h"
#include "mipointer.h"
@ -78,31 +79,36 @@ static Bool
xnestSaveScreen(ScreenPtr pScreen, int what)
{
if (xnestSoftwareScreenSaver)
return False;
return FALSE;
else {
switch (what) {
case SCREEN_SAVER_ON:
XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
xcb_map_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
uint32_t value = XCB_STACK_MODE_ABOVE;
xcb_configure_window(xnestUpstreamInfo.conn,
xnestScreenSaverWindows[pScreen->myNum],
XCB_CONFIG_WINDOW_STACK_MODE,
&value);
xnestSetScreenSaverColormapWindow(pScreen);
break;
case SCREEN_SAVER_OFF:
XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
xnestSetInstalledColormapWindows(pScreen);
break;
case SCREEN_SAVER_FORCER:
lastEventTime = GetTimeInMillis();
XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
xnestSetInstalledColormapWindows(pScreen);
break;
case SCREEN_SAVER_CYCLE:
XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
xnestSetInstalledColormapWindows(pScreen);
break;
}
return True;
return TRUE;
}
}
@ -132,17 +138,39 @@ static miPointerSpriteFuncRec xnestPointerSpriteFuncs = {
xnestDeviceCursorCleanup
};
static int addDepthVisual(DepthPtr depths, int numDepths, int nplanes, VisualID vid)
{
DepthPtr walk = NULL;
for (int j = 0; j < numDepths; j++)
if (depths[j].depth == nplanes) {
walk = &depths[j];
break;
}
if (!walk) {
walk = &depths[numDepths++];
walk->depth = nplanes;
walk->numVids = 0;
walk->vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
}
if (walk->numVids >= MAXVISUALSPERDEPTH) {
FatalError("Visual table overflow");
}
walk->vids[walk->numVids] = vid;
walk->numVids++;
return numDepths;
}
Bool
xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
{
VisualPtr visuals;
DepthPtr depths;
int numVisuals, numDepths;
int i, j, depthIndex;
int j;
unsigned long valuemask;
XSetWindowAttributes attributes;
XWindowAttributes gattributes;
XSizeHints sizeHints;
VisualID defaultVisual;
int rootDepth;
miPointerScreenPtr PointPriv;
@ -167,96 +195,128 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
PRIVATE_CURSOR, 0))
return FALSE;
visuals = xallocarray(xnestNumVisuals, sizeof(VisualRec));
visuals = xallocarray(1, sizeof(VisualRec));
numVisuals = 0;
if (!xnestVisualMap)
xnestVisualMap = calloc(1, sizeof(XnestVisualRec));
else
xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(XnestVisualRec));
depths = (DepthPtr) malloc(MAXDEPTH * sizeof(DepthRec));
depths[0].depth = 1;
depths[0].numVids = 0;
depths[0].vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
numDepths = 1;
for (i = 0; i < xnestNumVisuals; i++) {
visuals[numVisuals].class = xnestVisuals[i].class;
visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb;
visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size;
visuals[numVisuals].nplanes = xnestVisuals[i].depth;
visuals[numVisuals].redMask = xnestVisuals[i].red_mask;
visuals[numVisuals].greenMask = xnestVisuals[i].green_mask;
visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask;
visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask);
visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask);
visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask);
/* Check for and remove duplicates. */
for (j = 0; j < numVisuals; j++) {
if (visuals[numVisuals].class == visuals[j].class &&
visuals[numVisuals].bitsPerRGBValue ==
visuals[j].bitsPerRGBValue &&
visuals[numVisuals].ColormapEntries ==
visuals[j].ColormapEntries &&
visuals[numVisuals].nplanes == visuals[j].nplanes &&
visuals[numVisuals].redMask == visuals[j].redMask &&
visuals[numVisuals].greenMask == visuals[j].greenMask &&
visuals[numVisuals].blueMask == visuals[j].blueMask &&
visuals[numVisuals].offsetRed == visuals[j].offsetRed &&
visuals[numVisuals].offsetGreen == visuals[j].offsetGreen &&
visuals[numVisuals].offsetBlue == visuals[j].offsetBlue)
break;
}
if (j < numVisuals)
break;
visuals[numVisuals].vid = FakeClientID(0);
depthIndex = UNDEFINED;
for (j = 0; j < numDepths; j++)
if (depths[j].depth == xnestVisuals[i].depth) {
depthIndex = j;
break;
int found_default_visual = 0;
xcb_depth_iterator_t depth_iter;
for (depth_iter = xcb_screen_allowed_depths_iterator(xnestUpstreamInfo.screenInfo);
depth_iter.rem;
xcb_depth_next(&depth_iter))
{
int vlen = xcb_depth_visuals_length (depth_iter.data);
xcb_visualtype_t *vts = xcb_depth_visuals (depth_iter.data);
for (int x=0; x<vlen; x++) {
for (j = 0; j < numVisuals; j++) {
if (vts[x]._class == visuals[j].class &&
vts[x].bits_per_rgb_value == visuals[j].bitsPerRGBValue &&
vts[x].colormap_entries == visuals[j].ColormapEntries &&
depth_iter.data->depth == visuals[j].nplanes &&
vts[x].red_mask == visuals[j].redMask &&
vts[x].green_mask == visuals[j].greenMask &&
vts[x].blue_mask == visuals[j].blueMask &&
offset(vts[x].red_mask) == visuals[j].offsetRed &&
offset(vts[x].green_mask) == visuals[j].offsetGreen &&
offset(vts[x].blue_mask) == visuals[j].offsetBlue)
goto breakout;
}
if (depthIndex == UNDEFINED) {
depthIndex = numDepths;
depths[depthIndex].depth = xnestVisuals[i].depth;
depths[depthIndex].numVids = 0;
depths[depthIndex].vids =
(VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
numDepths++;
}
if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
FatalError("Visual table overflow");
}
depths[depthIndex].vids[depths[depthIndex].numVids] =
visuals[numVisuals].vid;
depths[depthIndex].numVids++;
visuals[numVisuals] = (VisualRec) {
.class = vts[x]._class,
.bitsPerRGBValue = vts[x].bits_per_rgb_value,
.ColormapEntries = vts[x].colormap_entries,
.nplanes = depth_iter.data->depth,
.redMask = vts[x].red_mask,
.greenMask = vts[x].green_mask,
.blueMask = vts[x].blue_mask,
.offsetRed = offset(vts[x].red_mask),
.offsetGreen = offset(vts[x].green_mask),
.offsetBlue = offset(vts[x].blue_mask),
.vid = FakeClientID(0),
};
numVisuals++;
xnestVisualMap[xnestNumVisualMap] = (XnestVisualRec) {
.ourXID = visuals[numVisuals].vid,
.ourVisual = &visuals[numVisuals],
.upstreamDepth = depth_iter.data,
.upstreamVisual = &vts[x],
.upstreamCMap = xcb_generate_id(xnestUpstreamInfo.conn),
};
xcb_create_colormap(xnestUpstreamInfo.conn,
XCB_COLORMAP_ALLOC_NONE,
xnestVisualMap[xnestNumVisualMap].upstreamCMap,
xnestUpstreamInfo.screenInfo->root,
xnestVisualMap[xnestNumVisualMap].upstreamVisual->visual_id);
numDepths = addDepthVisual(depths, numDepths, visuals[numVisuals].nplanes, visuals[numVisuals].vid);
if (xnestUserDefaultClass || xnestUserDefaultDepth) {
if ((!xnestDefaultClass || visuals[numVisuals].class == xnestDefaultClass) &&
(!xnestDefaultDepth || visuals[numVisuals].nplanes == xnestDefaultDepth))
{
defaultVisual = visuals[numVisuals].vid;
rootDepth = visuals[numVisuals].nplanes;
found_default_visual = 1;
}
}
else
{
VisualID visual_id = xnestUpstreamInfo.screenInfo->root_visual;
if (visual_id == vts[x].visual_id) {
defaultVisual = visuals[numVisuals].vid;
rootDepth = visuals[numVisuals].nplanes;
found_default_visual = 1;
}
}
numVisuals++;
xnestNumVisualMap++;
visuals = reallocarray(visuals, numVisuals+1, sizeof(VisualRec));
xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(XnestVisualRec));
}
}
breakout:
visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec));
xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap, sizeof(XnestVisualRec));
defaultVisual = visuals[xnestDefaultVisualIndex].vid;
rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
if (!found_default_visual) {
ErrorF("Xnest: can't find matching visual for user specified depth %d\n", xnestDefaultDepth);
defaultVisual = visuals[0].vid;
rootDepth = visuals[0].nplanes;
}
if (xnestParentWindow != 0) {
XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
xnestWidth = gattributes.width;
xnestHeight = gattributes.height;
xRectangle r = xnestGetGeometry(xnestUpstreamInfo.conn, xnestParentWindow);
xnestGeometry.width = r.width;
xnestGeometry.height = r.height;
}
/* myNum */
/* id */
if (!miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth, rootDepth, numDepths, depths, defaultVisual, /* root visual */
if (!miScreenInit(pScreen, NULL, xnestGeometry.width, xnestGeometry.height,
1, 1, xnestGeometry.width, rootDepth, numDepths, depths, defaultVisual, /* root visual */
numVisuals, visuals))
return FALSE;
pScreen->defColormap = (Colormap) FakeClientID(0);
pScreen->minInstalledCmaps = MINCMAPS;
pScreen->maxInstalledCmaps = MAXCMAPS;
pScreen->backingStoreSupport = NotUseful;
pScreen->saveUnderSupport = NotUseful;
pScreen->whitePixel = xnestWhitePixel;
pScreen->blackPixel = xnestBlackPixel;
pScreen->backingStoreSupport = XCB_BACKING_STORE_NOT_USEFUL;
pScreen->saveUnderSupport = XCB_BACKING_STORE_NOT_USEFUL;
pScreen->whitePixel = xnestUpstreamInfo.screenInfo->white_pixel;
pScreen->blackPixel = xnestUpstreamInfo.screenInfo->black_pixel;
/* GCperDepth */
/* defaultStipple */
/* WindowPrivateLen */
@ -282,9 +342,10 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
pScreen->RealizeWindow = xnestRealizeWindow;
pScreen->UnrealizeWindow = xnestUnrealizeWindow;
pScreen->PostValidateTree = NULL;
pScreen->WindowExposures = xnestWindowExposures;
pScreen->WindowExposures = miWindowExposures;
pScreen->CopyWindow = xnestCopyWindow;
pScreen->ClipNotify = xnestClipNotify;
pScreen->ClearToBackground = xnestClearToBackground;
/* Pixmap procedures */
@ -325,13 +386,12 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
&xnestCursorFuncs);
PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
DefaultScreen(xnestDisplay))
/ DisplayWidth(xnestDisplay, DefaultScreen(xnestDisplay));
pScreen->mmWidth =
xnestGeometry.width * xnestUpstreamInfo.screenInfo->width_in_millimeters /
xnestUpstreamInfo.screenInfo->width_in_pixels;
pScreen->mmHeight =
xnestHeight * DisplayHeightMM(xnestDisplay,
DefaultScreen(xnestDisplay)) /
DisplayHeight(xnestDisplay, DefaultScreen(xnestDisplay));
xnestGeometry.height * xnestUpstreamInfo.screenInfo->height_in_millimeters /
xnestUpstreamInfo.screenInfo->height_in_pixels;
/* overwrite miCloseScreen with our own */
pScreen->CloseScreen = xnestCloseScreen;
@ -341,74 +401,123 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
/* devPrivates */
#define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
#define POSITION_OFFSET (pScreen->myNum * (xnestGeometry.width + xnestGeometry.height) / 32)
if (xnestDoFullGeneration) {
valuemask = CWBackPixel | CWEventMask | CWColormap;
attributes.background_pixel = xnestWhitePixel;
attributes.event_mask = xnestEventMask;
attributes.colormap =
xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
XnSetWindowAttr attributes = {
.background_pixel = xnestUpstreamInfo.screenInfo->white_pixel,
.event_mask = xnestEventMask,
.colormap = xnestVisualToHostCmap(pScreen->rootVisual),
};
valuemask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
if (xnestParentWindow != 0) {
xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
XSelectInput(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
xnestEventMask);
xcb_change_window_attributes(xnestUpstreamInfo.conn,
xnestDefaultWindows[pScreen->myNum],
XCB_CW_EVENT_MASK,
&xnestEventMask);
}
else
xnestDefaultWindows[pScreen->myNum] =
XCreateWindow(xnestDisplay,
DefaultRootWindow(xnestDisplay),
xnestX + POSITION_OFFSET,
xnestY + POSITION_OFFSET,
xnestWidth, xnestHeight,
xnestBorderWidth,
else {
uint32_t values[32] = { 0 };
xnest_encode_window_attr(attributes, valuemask, values);
xnestDefaultWindows[pScreen->myNum] = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_window(xnestUpstreamInfo.conn,
pScreen->rootDepth,
InputOutput,
xnestDefaultVisual(pScreen),
valuemask, &attributes);
xnestDefaultWindows[pScreen->myNum],
xnestUpstreamInfo.screenInfo->root,
xnestGeometry.x + POSITION_OFFSET,
xnestGeometry.y + POSITION_OFFSET,
xnestGeometry.width,
xnestGeometry.height,
xnestBorderWidth,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
xnest_visual_map_to_host(pScreen->rootVisual),
valuemask,
values);
}
if (!xnestWindowName)
xnestWindowName = argv[0];
sizeHints.flags = PPosition | PSize | PMaxSize;
sizeHints.x = xnestX + POSITION_OFFSET;
sizeHints.y = xnestY + POSITION_OFFSET;
sizeHints.width = sizeHints.max_width = xnestWidth;
sizeHints.height = sizeHints.max_height = xnestHeight;
if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
sizeHints.flags |= USPosition;
if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
sizeHints.flags |= USSize;
XSetStandardProperties(xnestDisplay,
xnestDefaultWindows[pScreen->myNum],
xnestWindowName,
xnestWindowName,
xnestIconBitmap, argv, argc, &sizeHints);
xcb_size_hints_t sizeHints = {
.flags = XCB_ICCCM_SIZE_HINT_P_POSITION | XCB_ICCCM_SIZE_HINT_P_SIZE | XCB_ICCCM_SIZE_HINT_P_MAX_SIZE,
.x = xnestGeometry.x + POSITION_OFFSET,
.y = xnestGeometry.y + POSITION_OFFSET,
.width = xnestGeometry.width,
.height = xnestGeometry.height,
.max_width = xnestGeometry.width,
.max_height = xnestGeometry.height,
};
XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
if (xnestUserGeometry & XCB_CONFIG_WINDOW_X ||
xnestUserGeometry & XCB_CONFIG_WINDOW_Y)
sizeHints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION;
if (xnestUserGeometry & XCB_CONFIG_WINDOW_WIDTH ||
xnestUserGeometry & XCB_CONFIG_WINDOW_HEIGHT)
sizeHints.flags |= XCB_ICCCM_SIZE_HINT_US_SIZE;
valuemask = CWBackPixmap | CWColormap;
const size_t windowNameLen = strlen(xnestWindowName);
xcb_icccm_set_wm_name_checked(xnestUpstreamInfo.conn,
xnestDefaultWindows[pScreen->myNum],
XCB_ATOM_STRING,
8,
windowNameLen,
xnestWindowName);
xcb_icccm_set_wm_icon_name_checked(xnestUpstreamInfo.conn,
xnestDefaultWindows[pScreen->myNum],
XCB_ATOM_STRING,
8,
windowNameLen,
xnestWindowName);
xnestSetCommand(xnestUpstreamInfo.conn,
xnestDefaultWindows[pScreen->myNum],
argv, argc);
xcb_icccm_wm_hints_t wmhints = {
.icon_pixmap = xnestIconBitmap,
.flags = XCB_ICCCM_WM_HINT_ICON_PIXMAP,
};
xcb_icccm_set_wm_hints_checked(xnestUpstreamInfo.conn,
xnestDefaultWindows[pScreen->myNum],
&wmhints);
xcb_map_window(xnestUpstreamInfo.conn, xnestDefaultWindows[pScreen->myNum]);
valuemask = XCB_CW_BACK_PIXMAP | XCB_CW_COLORMAP;
attributes.background_pixmap = xnestScreenSaverPixmap;
attributes.colormap =
DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
xnestScreenSaverWindows[pScreen->myNum] =
XCreateWindow(xnestDisplay,
attributes.colormap = xnestUpstreamInfo.screenInfo->default_colormap;
uint32_t values[32] = { 0 };
xnest_encode_window_attr(attributes, valuemask, values);
xnestScreenSaverWindows[pScreen->myNum] = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_window(xnestUpstreamInfo.conn,
xnestUpstreamInfo.screenInfo->root_depth,
xnestScreenSaverWindows[pScreen->myNum],
xnestDefaultWindows[pScreen->myNum],
0, 0, xnestWidth, xnestHeight, 0,
DefaultDepth(xnestDisplay,
DefaultScreen(xnestDisplay)),
InputOutput, DefaultVisual(xnestDisplay,
DefaultScreen
(xnestDisplay)), valuemask,
&attributes);
0,
0,
xnestGeometry.width,
xnestGeometry.height,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
xnestUpstreamInfo.screenInfo->root_visual,
valuemask,
values);
}
if (!xnestCreateDefaultColormap(pScreen))
return False;
return FALSE;
return True;
return TRUE;
}
Bool
@ -427,5 +536,5 @@ xnestCloseScreen(ScreenPtr pScreen)
the display connection. There is no need to generate extra protocol.
*/
return True;
return TRUE;
}

View File

@ -1,69 +0,0 @@
/*
Copyright 1993 by Davor Matic
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation. Davor Matic makes no representations about
the suitability of this software for any purpose. It is provided "as
is" without express or implied warranty.
*/
#ifdef HAVE_XNEST_CONFIG_H
#include <xnest-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "scrnintstr.h"
#include "dix.h"
#include "mi.h"
#include "Xnest.h"
#include "Display.h"
#include "Visual.h"
Visual *
xnestVisual(VisualPtr pVisual)
{
int i;
for (i = 0; i < xnestNumVisuals; i++)
if (pVisual->class == xnestVisuals[i].class &&
pVisual->bitsPerRGBValue == xnestVisuals[i].bits_per_rgb &&
pVisual->ColormapEntries == xnestVisuals[i].colormap_size &&
pVisual->nplanes == xnestVisuals[i].depth &&
pVisual->redMask == xnestVisuals[i].red_mask &&
pVisual->greenMask == xnestVisuals[i].green_mask &&
pVisual->blueMask == xnestVisuals[i].blue_mask)
return xnestVisuals[i].visual;
return NULL;
}
Visual *
xnestVisualFromID(ScreenPtr pScreen, VisualID visual)
{
int i;
for (i = 0; i < pScreen->numVisuals; i++)
if (pScreen->visuals[i].vid == visual)
return xnestVisual(&pScreen->visuals[i]);
return NULL;
}
Colormap
xnestDefaultVisualColormap(Visual * visual)
{
int i;
for (i = 0; i < xnestNumVisuals; i++)
if (xnestVisuals[i].visual == visual)
return xnestDefaultColormaps[i];
return None;
}

View File

@ -1,27 +0,0 @@
/*
Copyright 1993 by Davor Matic
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation. Davor Matic makes no representations about
the suitability of this software for any purpose. It is provided "as
is" without express or implied warranty.
*/
#ifndef XNESTVISUAL_H
#define XNESTVISUAL_H
#include <X11/X.h>
Visual *xnestVisual(VisualPtr pVisual);
Visual *xnestVisualFromID(ScreenPtr pScreen, VisualID visual);
Colormap xnestDefaultVisualColormap(Visual * visual);
#define xnestDefaultVisual(pScreen) \
xnestVisualFromID((pScreen), (pScreen)->rootVisual)
#endif /* XNESTVISUAL_H */

View File

@ -16,6 +16,9 @@ is" without express or implied warranty.
#include <xnest-config.h>
#endif
#include <xcb/xcb.h>
#include <xcb/shape.h>
#include <X11/X.h>
#include <X11/Xdefs.h>
#include <X11/Xproto.h>
@ -30,14 +33,13 @@ is" without express or implied warranty.
#include "mi.h"
#include "Xnest.h"
#include "xnest-xcb.h"
#include "Display.h"
#include "Screen.h"
#include "XNGC.h"
#include "Drawable.h"
#include "Color.h"
#include "Visual.h"
#include "Events.h"
#include "Args.h"
@ -78,25 +80,25 @@ Bool
xnestCreateWindow(WindowPtr pWin)
{
unsigned long mask;
XSetWindowAttributes attributes;
Visual *visual;
XnSetWindowAttr attributes = { 0 };
uint32_t visual = CopyFromParent; /* 0L */
ColormapPtr pCmap;
uint32_t params[32] = { 0 };
if (pWin->drawable.class == InputOnly) {
mask = 0L;
visual = CopyFromParent;
}
else {
mask = CWEventMask | CWBackingStore;
attributes.event_mask = ExposureMask;
attributes.backing_store = NotUseful;
mask = XCB_CW_EVENT_MASK | XCB_CW_BACKING_STORE;
attributes.event_mask = XCB_EVENT_MASK_EXPOSURE;
attributes.backing_store = XCB_BACKING_STORE_NOT_USEFUL;
if (pWin->parent) {
if (pWin->optional &&
pWin->optional->visual != wVisual(pWin->parent)) {
visual =
xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
mask |= CWColormap;
visual = xnest_visual_map_to_host(wVisual(pWin));
mask |= XCB_CW_COLORMAP;
if (pWin->optional->colormap) {
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
X11_RESTYPE_COLORMAP, serverClient,
@ -104,39 +106,43 @@ xnestCreateWindow(WindowPtr pWin)
attributes.colormap = xnestColormap(pCmap);
}
else
attributes.colormap = xnestDefaultVisualColormap(visual);
attributes.colormap = xnestHostVisualToHostCmap(visual);
}
else
visual = CopyFromParent;
}
else { /* root windows have their own colormaps at creation time */
visual = xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
visual = xnest_visual_map_to_host(wVisual(pWin));
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
X11_RESTYPE_COLORMAP, serverClient, DixUseAccess);
mask |= CWColormap;
mask |= XCB_CW_COLORMAP;
attributes.colormap = xnestColormap(pCmap);
}
}
xnestWindowPriv(pWin)->window = XCreateWindow(xnestDisplay,
xnestWindowParent(pWin),
pWin->origin.x -
wBorderWidth(pWin),
pWin->origin.y -
wBorderWidth(pWin),
pWin->drawable.width,
pWin->drawable.height,
pWin->borderWidth,
pWin->drawable.depth,
pWin->drawable.class,
visual, mask, &attributes);
xnestWindowPriv(pWin)->window = xcb_generate_id(xnestUpstreamInfo.conn);
xnest_encode_window_attr(attributes, mask, params);
xcb_create_window(xnestUpstreamInfo.conn,
pWin->drawable.depth,
xnestWindowPriv(pWin)->window,
xnestWindowParent(pWin),
pWin->origin.x - wBorderWidth(pWin),
pWin->origin.y - wBorderWidth(pWin),
pWin->drawable.width,
pWin->drawable.height,
pWin->borderWidth,
pWin->drawable.class,
visual,
mask,
&params);
xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
xnestWindowPriv(pWin)->width = pWin->drawable.width;
xnestWindowPriv(pWin)->height = pWin->drawable.height;
xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
xnestWindowPriv(pWin)->sibling_above = None;
xnestWindowPriv(pWin)->sibling_above = XCB_WINDOW_NONE;
if (pWin->nextSib)
xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
xnestWindowPriv(pWin)->bounding_shape = RegionCreate(NULL, 1);
@ -145,7 +151,7 @@ xnestCreateWindow(WindowPtr pWin)
if (!pWin->parent) /* only the root window will have the right colormap */
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
return True;
return TRUE;
}
Bool
@ -156,83 +162,90 @@ xnestDestroyWindow(WindowPtr pWin)
xnestWindowPriv(pWin)->sibling_above;
RegionDestroy(xnestWindowPriv(pWin)->bounding_shape);
RegionDestroy(xnestWindowPriv(pWin)->clip_shape);
XDestroyWindow(xnestDisplay, xnestWindow(pWin));
xnestWindowPriv(pWin)->window = None;
xcb_destroy_window(xnestUpstreamInfo.conn, xnestWindow(pWin));
xnestWindowPriv(pWin)->window = XCB_WINDOW_NONE;
if (pWin->optional && pWin->optional->colormap && pWin->parent)
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
return True;
return TRUE;
}
Bool
xnestPositionWindow(WindowPtr pWin, int x, int y)
{
xnestConfigureWindow(pWin,
CWParent |
CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
XCB_CONFIG_WINDOW_SIBLING | \
XCB_CONFIG_WINDOW_X | \
XCB_CONFIG_WINDOW_Y | \
XCB_CONFIG_WINDOW_WIDTH | \
XCB_CONFIG_WINDOW_HEIGHT | \
XCB_CONFIG_WINDOW_BORDER_WIDTH);
return True;
return TRUE;
}
void
xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
{
unsigned int valuemask;
XWindowChanges values;
XnWindowChanges values;
if (mask & CWParent &&
if (mask & XCB_CONFIG_WINDOW_SIBLING &&
xnestWindowPriv(pWin)->parent != xnestWindowParent(pWin)) {
XReparentWindow(xnestDisplay, xnestWindow(pWin),
xnestWindowParent(pWin),
pWin->origin.x - wBorderWidth(pWin),
pWin->origin.y - wBorderWidth(pWin));
xcb_reparent_window(
xnestUpstreamInfo.conn,
xnestWindow(pWin),
xnestWindowParent(pWin),
pWin->origin.x - wBorderWidth(pWin),
pWin->origin.y - wBorderWidth(pWin));
xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
xnestWindowPriv(pWin)->sibling_above = None;
xnestWindowPriv(pWin)->sibling_above = XCB_WINDOW_NONE;
if (pWin->nextSib)
xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
}
valuemask = 0;
if (mask & CWX &&
if (mask & XCB_CONFIG_WINDOW_X &&
xnestWindowPriv(pWin)->x != pWin->origin.x - wBorderWidth(pWin)) {
valuemask |= CWX;
valuemask |= XCB_CONFIG_WINDOW_X;
values.x =
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
}
if (mask & CWY &&
if (mask & XCB_CONFIG_WINDOW_Y &&
xnestWindowPriv(pWin)->y != pWin->origin.y - wBorderWidth(pWin)) {
valuemask |= CWY;
valuemask |= XCB_CONFIG_WINDOW_Y;
values.y =
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
}
if (mask & CWWidth && xnestWindowPriv(pWin)->width != pWin->drawable.width) {
valuemask |= CWWidth;
if (mask & XCB_CONFIG_WINDOW_WIDTH && xnestWindowPriv(pWin)->width != pWin->drawable.width) {
valuemask |= XCB_CONFIG_WINDOW_WIDTH;
values.width = xnestWindowPriv(pWin)->width = pWin->drawable.width;
}
if (mask & CWHeight &&
if (mask & XCB_CONFIG_WINDOW_HEIGHT &&
xnestWindowPriv(pWin)->height != pWin->drawable.height) {
valuemask |= CWHeight;
valuemask |= XCB_CONFIG_WINDOW_HEIGHT;
values.height = xnestWindowPriv(pWin)->height = pWin->drawable.height;
}
if (mask & CWBorderWidth &&
if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH &&
xnestWindowPriv(pWin)->border_width != pWin->borderWidth) {
valuemask |= CWBorderWidth;
valuemask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
values.border_width =
xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
}
if (valuemask)
XConfigureWindow(xnestDisplay, xnestWindow(pWin), valuemask, &values);
xnest_configure_window(xnestUpstreamInfo.conn, xnestWindow(pWin), valuemask, values);
if (mask & CWStackingOrder &&
if (mask & XCB_CONFIG_WINDOW_SIBLING &&
xnestWindowPriv(pWin)->sibling_above != xnestWindowSiblingAbove(pWin)) {
WindowPtr pSib;
@ -240,18 +253,18 @@ xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib);
/* the top sibling */
valuemask = CWStackMode;
valuemask = XCB_CONFIG_WINDOW_STACK_MODE;
values.stack_mode = Above;
XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask, &values);
xnestWindowPriv(pSib)->sibling_above = None;
xnest_configure_window(xnestUpstreamInfo.conn, xnestWindow(pSib), valuemask, values);
xnestWindowPriv(pSib)->sibling_above = XCB_WINDOW_NONE;
/* the rest of siblings */
for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib) {
valuemask = CWSibling | CWStackMode;
valuemask = XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE;
values.sibling = xnestWindowSiblingAbove(pSib);
values.stack_mode = Below;
XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask,
&values);
xnest_configure_window(xnestUpstreamInfo.conn, xnestWindow(pSib), valuemask, values);
xnestWindowPriv(pSib)->sibling_above =
xnestWindowSiblingAbove(pSib);
}
@ -261,15 +274,15 @@ xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
Bool
xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
{
XSetWindowAttributes attributes;
XnSetWindowAttr attributes;
if (mask & CWBackPixmap)
if (mask & XCB_CW_BACK_PIXMAP)
switch (pWin->backgroundState) {
case None:
attributes.background_pixmap = None;
case XCB_BACK_PIXMAP_NONE:
attributes.background_pixmap = XCB_PIXMAP_NONE;
break;
case ParentRelative:
case XCB_BACK_PIXMAP_PARENT_RELATIVE:
attributes.background_pixmap = ParentRelative;
break;
@ -278,59 +291,59 @@ xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
break;
case BackgroundPixel:
mask &= ~CWBackPixmap;
mask &= ~XCB_CW_BACK_PIXMAP;
break;
}
if (mask & CWBackPixel) {
if (mask & XCB_CW_BACK_PIXEL) {
if (pWin->backgroundState == BackgroundPixel)
attributes.background_pixel = xnestPixel(pWin->background.pixel);
else
mask &= ~CWBackPixel;
mask &= ~XCB_CW_BACK_PIXEL;
}
if (mask & CWBorderPixmap) {
if (mask & XCB_CW_BORDER_PIXMAP) {
if (pWin->borderIsPixel)
mask &= ~CWBorderPixmap;
mask &= ~XCB_CW_BORDER_PIXMAP;
else
attributes.border_pixmap = xnestPixmap(pWin->border.pixmap);
}
if (mask & CWBorderPixel) {
if (mask & XCB_CW_BORDER_PIXEL) {
if (pWin->borderIsPixel)
attributes.border_pixel = xnestPixel(pWin->border.pixel);
else
mask &= ~CWBorderPixel;
mask &= ~XCB_CW_BORDER_PIXEL;
}
if (mask & CWBitGravity)
if (mask & XCB_CW_BIT_GRAVITY)
attributes.bit_gravity = pWin->bitGravity;
if (mask & CWWinGravity) /* dix does this for us */
mask &= ~CWWinGravity;
if (mask & XCB_CW_WIN_GRAVITY) /* dix does this for us */
mask &= ~XCB_CW_WIN_GRAVITY;
if (mask & CWBackingStore) /* this is really not useful */
mask &= ~CWBackingStore;
if (mask & XCB_CW_BACKING_STORE) /* this is really not useful */
mask &= ~XCB_CW_BACKING_STORE;
if (mask & CWBackingPlanes) /* this is really not useful */
mask &= ~CWBackingPlanes;
if (mask & XCB_CW_BACKING_PLANES) /* this is really not useful */
mask &= ~XCB_CW_BACKING_PLANES;
if (mask & CWBackingPixel) /* this is really not useful */
mask &= ~CWBackingPixel;
if (mask & XCB_CW_BACKING_PIXEL) /* this is really not useful */
mask &= ~XCB_CW_BACKING_PIXEL;
if (mask & CWOverrideRedirect)
if (mask & XCB_CW_OVERRIDE_REDIRECT)
attributes.override_redirect = pWin->overrideRedirect;
if (mask & CWSaveUnder) /* this is really not useful */
mask &= ~CWSaveUnder;
if (mask & XCB_CW_SAVE_UNDER) /* this is really not useful */
mask &= ~XCB_CW_SAVE_UNDER;
if (mask & CWEventMask) /* events are handled elsewhere */
mask &= ~CWEventMask;
if (mask & XCB_CW_EVENT_MASK) /* events are handled elsewhere */
mask &= ~XCB_CW_EVENT_MASK;
if (mask & CWDontPropagate) /* events are handled elsewhere */
mask &= ~CWDontPropagate;
if (mask & XCB_CW_DONT_PROPAGATE) /* events are handled elsewhere */
mask &= ~XCB_CW_DONT_PROPAGATE;
if (mask & CWColormap) {
if (mask & XCB_CW_COLORMAP) {
ColormapPtr pCmap;
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
@ -341,32 +354,35 @@ xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
}
if (mask & CWCursor) /* this is handled in cursor code */
mask &= ~CWCursor;
if (mask & XCB_CW_CURSOR) /* this is handled in cursor code */
mask &= ~XCB_CW_CURSOR;
if (mask)
XChangeWindowAttributes(xnestDisplay, xnestWindow(pWin),
mask, &attributes);
return True;
if (mask) {
uint32_t values[32];
xnest_encode_window_attr(attributes, mask, values);
xcb_change_window_attributes(xnestUpstreamInfo.conn,
xnestWindow(pWin),
mask,
values);
}
return TRUE;
}
Bool
xnestRealizeWindow(WindowPtr pWin)
{
xnestConfigureWindow(pWin, CWStackingOrder);
xnestConfigureWindow(pWin, XCB_CONFIG_WINDOW_SIBLING);
xnestShapeWindow(pWin);
XMapWindow(xnestDisplay, xnestWindow(pWin));
xcb_map_window(xnestUpstreamInfo.conn, xnestWindow(pWin));
return True;
return TRUE;
}
Bool
xnestUnrealizeWindow(WindowPtr pWin)
{
XUnmapWindow(xnestDisplay, xnestWindow(pWin));
return True;
xcb_unmap_window(xnestUpstreamInfo.conn, xnestWindow(pWin));
return TRUE;
}
void
@ -377,44 +393,10 @@ xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion)
void
xnestClipNotify(WindowPtr pWin, int dx, int dy)
{
xnestConfigureWindow(pWin, CWStackingOrder);
xnestConfigureWindow(pWin, XCB_CONFIG_WINDOW_SIBLING);
xnestShapeWindow(pWin);
}
static Bool
xnestWindowExposurePredicate(Display * dpy, XEvent * event, XPointer ptr)
{
return (event->type == Expose && event->xexpose.window == *(Window *) ptr);
}
void
xnestWindowExposures(WindowPtr pWin, RegionPtr pRgn)
{
XEvent event;
Window window;
BoxRec Box;
XSync(xnestDisplay, False);
window = xnestWindow(pWin);
while (XCheckIfEvent(xnestDisplay, &event,
xnestWindowExposurePredicate, (char *) &window)) {
Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + event.xexpose.x;
Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + event.xexpose.y;
Box.x2 = Box.x1 + event.xexpose.width;
Box.y2 = Box.y1 + event.xexpose.height;
event.xexpose.type = ProcessedExpose;
if (RegionContainsRect(pRgn, &Box) != rgnIN)
XPutBackEvent(xnestDisplay, &event);
}
miWindowExposures(pWin, pRgn);
}
void
xnestSetShape(WindowPtr pWin, int kind)
{
@ -429,10 +411,10 @@ xnestRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
unsigned int n1, n2;
if (pReg1 == pReg2)
return True;
return TRUE;
if (pReg1 == NullRegion || pReg2 == NullRegion)
return False;
return FALSE;
pBox1 = RegionRects(pReg1);
n1 = RegionNumRects(pReg1);
@ -441,25 +423,20 @@ xnestRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
n2 = RegionNumRects(pReg2);
if (n1 != n2)
return False;
return FALSE;
if (pBox1 == pBox2)
return True;
return TRUE;
if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec)))
return False;
return FALSE;
return True;
return TRUE;
}
void
xnestShapeWindow(WindowPtr pWin)
{
Region reg;
BoxPtr pBox;
XRectangle rect;
int i;
if (!xnestRegionEqual(xnestWindowPriv(pWin)->bounding_shape,
wBoundingShape(pWin))) {
@ -467,26 +444,27 @@ xnestShapeWindow(WindowPtr pWin)
RegionCopy(xnestWindowPriv(pWin)->bounding_shape,
wBoundingShape(pWin));
reg = XCreateRegion();
pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape);
for (i = 0;
i < RegionNumRects(xnestWindowPriv(pWin)->bounding_shape);
i++) {
rect.x = pBox[i].x1;
rect.y = pBox[i].y1;
rect.width = pBox[i].x2 - pBox[i].x1;
rect.height = pBox[i].y2 - pBox[i].y1;
XUnionRectWithRegion(&rect, reg, reg);
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->bounding_shape);
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape);
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
for (int i = 0; i < num_rects; i++) {
rects[i].x = pBox[i].x1;
rects[i].y = pBox[i].y1;
rects[i].width = pBox[i].x2 - pBox[i].x1;
rects[i].height = pBox[i].y2 - pBox[i].y1;
}
XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
ShapeBounding, 0, 0, reg, ShapeSet);
XDestroyRegion(reg);
xcb_shape_rectangles(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_YX_BANDED,
xnestWindow(pWin), 0, 0, num_rects, rects);
free(rects);
}
else {
RegionEmpty(xnestWindowPriv(pWin)->bounding_shape);
XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
ShapeBounding, 0, 0, None, ShapeSet);
xcb_shape_mask(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
XCB_SHAPE_SK_BOUNDING, xnestWindow(pWin),
0, 0, XCB_PIXMAP_NONE);
}
}
@ -495,25 +473,34 @@ xnestShapeWindow(WindowPtr pWin)
if (wClipShape(pWin)) {
RegionCopy(xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin));
reg = XCreateRegion();
pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape);
for (i = 0;
i < RegionNumRects(xnestWindowPriv(pWin)->clip_shape); i++) {
rect.x = pBox[i].x1;
rect.y = pBox[i].y1;
rect.width = pBox[i].x2 - pBox[i].x1;
rect.height = pBox[i].y2 - pBox[i].y1;
XUnionRectWithRegion(&rect, reg, reg);
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->clip_shape);
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape);
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
for (int i = 0; i < num_rects; i++) {
rects[i].x = pBox[i].x1;
rects[i].y = pBox[i].y1;
rects[i].width = pBox[i].x2 - pBox[i].x1;
rects[i].height = pBox[i].y2 - pBox[i].y1;
}
XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
ShapeClip, 0, 0, reg, ShapeSet);
XDestroyRegion(reg);
xcb_shape_rectangles(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
XCB_SHAPE_SK_CLIP, XCB_CLIP_ORDERING_YX_BANDED,
xnestWindow(pWin), 0, 0, num_rects, rects);
free(rects);
}
else {
RegionEmpty(xnestWindowPriv(pWin)->clip_shape);
XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
ShapeClip, 0, 0, None, ShapeSet);
xcb_shape_mask(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
XCB_SHAPE_SK_CLIP, xnestWindow(pWin), 0, 0, XCB_PIXMAP_NONE);
}
}
}
void xnestClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures)
{
xcb_clear_area(xnestUpstreamInfo.conn,
generateExposures,
xnestWindow(pWin),
x, y, w, h);
}

View File

@ -17,19 +17,13 @@ is" without express or implied warranty.
#include <X11/Xdefs.h>
typedef struct {
XFontStruct *font_struct;
} xnestPrivFont;
#include <xcb/xcb.h>
extern int xnestFontPrivateIndex;
#define xnestFontPriv(pFont) \
((xnestPrivFont *)FontGetPrivate(pFont, xnestFontPrivateIndex))
#define xnestFontStruct(pFont) (xnestFontPriv(pFont)->font_struct)
#define xnestFont(pFont) (xnestFontStruct(pFont)->fid)
Bool xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont);
Bool xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);

View File

@ -17,10 +17,11 @@ is" without express or implied warranty.
#include <X11/Xdefs.h>
/* This file uses the GC definition form Xlib.h as XlibGC. */
#include "include/gcstruct.h"
#include "include/privates.h"
typedef struct {
XlibGC gc;
uint32_t gc;
} xnestPrivGC;
extern DevPrivateKeyRec xnestGCPrivateKeyRec;

View File

@ -50,13 +50,10 @@ extern DevPrivateKeyRec xnestWindowPrivateKeyRec;
xnestDefaultWindows[pWin->drawable.pScreen->myNum])
#define xnestWindowSiblingAbove(pWin) \
((pWin)->prevSib ? xnestWindow((pWin)->prevSib) : None)
((pWin)->prevSib ? xnestWindow((pWin)->prevSib) : XCB_WINDOW_NONE)
#define xnestWindowSiblingBelow(pWin) \
((pWin)->nextSib ? xnestWindow((pWin)->nextSib) : None)
#define CWParent CWSibling
#define CWStackingOrder CWStackMode
((pWin)->nextSib ? xnestWindow((pWin)->nextSib) : XCB_WINDOW_NONE)
WindowPtr xnestWindowPtr(Window window);
Bool xnestCreateWindow(WindowPtr pWin);
@ -68,8 +65,8 @@ Bool xnestRealizeWindow(WindowPtr pWin);
Bool xnestUnrealizeWindow(WindowPtr pWin);
void xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion);
void xnestClipNotify(WindowPtr pWin, int dx, int dy);
void xnestWindowExposures(WindowPtr pWin, RegionPtr pRgn);
void xnestSetShape(WindowPtr pWin, int kind);
void xnestShapeWindow(WindowPtr pWin);
void xnestClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures);
#endif /* XNESTWINDOW_H */

View File

@ -1,90 +0,0 @@
/*
Copyright (c) 1995 X Consortium
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the X Consortium shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from the X Consortium.
*/
/*
** Machines with a 64 bit library interface and a 32 bit server require
** name changes to protect the guilty.
*/
#ifdef _XSERVER64
#define _XSERVER64_tmp
#undef _XSERVER64
typedef unsigned long XID64;
typedef unsigned long Mask64;
typedef unsigned long Atom64;
typedef unsigned long VisualID64;
typedef unsigned long Time64;
#define XID XID64
#define Mask Mask64
#define Atom Atom64
#define VisualID VisualID64
#define Time Time64
typedef XID Window64;
typedef XID Drawable64;
typedef XID Font64;
typedef XID Pixmap64;
typedef XID Cursor64;
typedef XID Colormap64;
typedef XID GContext64;
typedef XID KeySym64;
#define Window Window64
#define Drawable Drawable64
#define Font Font64
#define Pixmap Pixmap64
#define Cursor Cursor64
#define Colormap Colormap64
#define GContext GContext64
#define KeySym KeySym64
#endif /*_XSERVER64*/
#define GC XlibGC
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
#undef GC
#ifdef _XSERVER64_tmp
#define _XSERVER64
#undef _XSERVER64_tmp
#undef XID
#undef Mask
#undef Atom
#undef VisualID
#undef Time
#undef Window
#undef Drawable
#undef Font
#undef Pixmap
#undef Cursor
#undef Colormap
#undef GContext
#undef KeySym
#endif /*_XSERVER64_tmp*/

View File

@ -13,19 +13,28 @@ srcs = [
'Pixmap.c',
'Pointer.c',
'Screen.c',
'Visual.c',
'Window.c',
'../../mi/miinitext.c',
'../../mi/miinitext.h',
'xcb.c',
'xkb.c',
]
xcb_dep = dependency('xcb', required: true)
xcb_shape_dep = dependency('xcb-shape', required: true)
xcb_icccm_dep = dependency('xcb-icccm', required: true)
xcb_xkb_dep = dependency('xcb-xkb', required: true)
executable(
'Xnest',
srcs,
include_directories: inc,
dependencies: [
common_dep,
xnest_dep,
xcb_dep,
xcb_shape_dep,
xcb_icccm_dep,
xcb_xkb_dep,
],
link_with: [
libxserver_main,

676
hw/xnest/xcb.c Normal file
View File

@ -0,0 +1,676 @@
/* SPDX-License-Identifier: MIT OR X11
*
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
*/
#include <dix-config.h>
#include <xcb/xcb.h>
#include <xcb/xcb_icccm.h>
#include <X11/X.h>
#include <X11/Xdefs.h>
#include <X11/Xproto.h>
#include <xcb/xkb.h>
#include "include/gc.h"
#include "include/servermd.h"
#include "xnest-xcb.h"
#include "xnest-xkb.h"
#include "XNGC.h"
#include "Display.h"
xnestUpstreamInfoRec xnestUpstreamInfo = { 0 };
XnestVisualRec *xnestVisualMap;
int xnestNumVisualMap;
Bool xnest_upstream_setup(const char* displayName)
{
xnestUpstreamInfo.conn = xcb_connect(displayName, &xnestUpstreamInfo.screenId);
if (!xnestUpstreamInfo.conn)
return FALSE;
/* retrieve setup data for our screen */
xnestUpstreamInfo.setup = xcb_get_setup(xnestUpstreamInfo.conn);
xcb_screen_iterator_t iter = xcb_setup_roots_iterator (xnestUpstreamInfo.setup);
for (int i = 0; i < xnestUpstreamInfo.screenId; ++i)
xcb_screen_next (&iter);
xnestUpstreamInfo.screenInfo = iter.data;
xorg_list_init(&xnestUpstreamInfo.eventQueue.entry);
return TRUE;
}
/* retrieve upstream GC XID for our xserver GC */
uint32_t xnestUpstreamGC(GCPtr pGC) {
if (pGC == NULL) return 0;
xnestPrivGC *priv = dixLookupPrivate(&(pGC)->devPrivates, xnestGCPrivateKey);
if (priv == NULL) return 0;
return priv->gc;
}
void xnest_encode_window_attr(XnSetWindowAttr attr, uint32_t mask, uint32_t *values)
{
int idx = 0;
#define EXTRA_VALUE(flag,val) if (mask & flag) { values[idx++] = attr.val; }
EXTRA_VALUE(XCB_CW_BACK_PIXMAP, background_pixmap);
EXTRA_VALUE(XCB_CW_BACK_PIXEL, background_pixel)
EXTRA_VALUE(XCB_CW_BORDER_PIXMAP, border_pixmap)
EXTRA_VALUE(XCB_CW_BORDER_PIXEL, border_pixel)
EXTRA_VALUE(XCB_CW_BIT_GRAVITY, bit_gravity)
EXTRA_VALUE(XCB_CW_WIN_GRAVITY, win_gravity);
EXTRA_VALUE(XCB_CW_BACKING_STORE, backing_store);
EXTRA_VALUE(XCB_CW_BACKING_PLANES, backing_planes);
EXTRA_VALUE(XCB_CW_BACKING_PIXEL, backing_pixel);
EXTRA_VALUE(XCB_CW_OVERRIDE_REDIRECT, override_redirect);
EXTRA_VALUE(XCB_CW_SAVE_UNDER, save_under);
EXTRA_VALUE(XCB_CW_EVENT_MASK, event_mask);
EXTRA_VALUE(XCB_CW_DONT_PROPAGATE, do_not_propagate_mask);
EXTRA_VALUE(XCB_CW_COLORMAP, colormap);
EXTRA_VALUE(XCB_CW_CURSOR, cursor);
#undef EXTRA_VALUE
}
void xnest_configure_window(xcb_connection_t *conn, uint32_t window,
uint32_t mask, XnWindowChanges values)
{
if (mask) {
uint32_t value_list[16] = { 0 };
int idx = 0;
#define EXTRA_VALUE(flag,val) if (mask & flag) { value_list[idx++] = values.val; }
EXTRA_VALUE(XCB_CONFIG_WINDOW_X, x);
EXTRA_VALUE(XCB_CONFIG_WINDOW_Y, y);
EXTRA_VALUE(XCB_CONFIG_WINDOW_WIDTH, width);
EXTRA_VALUE(XCB_CONFIG_WINDOW_HEIGHT, height);
EXTRA_VALUE(XCB_CONFIG_WINDOW_BORDER_WIDTH, border_width);
EXTRA_VALUE(XCB_CONFIG_WINDOW_SIBLING, sibling);
EXTRA_VALUE(XCB_CONFIG_WINDOW_STACK_MODE, stack_mode);
#undef EXTRA_VALUE
xcb_configure_window(conn, window, mask, value_list);
}
}
void xnestEncodeKeyboardControl(XnKeyboardControl ctrl, long mask, uint32_t *value)
{
if (mask & KBKeyClickPercent)
*value++ = ctrl.key_click_percent;
if (mask & KBBellPercent)
*value++ = ctrl.bell_percent;
if (mask & KBBellPitch)
*value++ = ctrl.bell_pitch;
if (mask & KBBellDuration)
*value++ = ctrl.bell_duration;
if (mask & KBLed)
*value++ = ctrl.led;
if (mask & KBLedMode)
*value++ = ctrl.led_mode;
if (mask & KBKey)
*value++ = ctrl.key;
if (mask & KBAutoRepeatMode)
*value++ = ctrl.auto_repeat_mode;
}
void xnChangeGC(xcb_connection_t *conn, uint32_t gc, XnGCValues gcval, uint32_t mask)
{
char value_list[128] = { 0 };
char *walk = value_list;
#define EXTRA_VALUE(flag,val) if (mask & flag) { *((uint32_t*)walk) = gcval.val; walk+=4; }
EXTRA_VALUE(GCFunction, function);
EXTRA_VALUE(GCPlaneMask, plane_mask);
EXTRA_VALUE(GCForeground, foreground);
EXTRA_VALUE(GCBackground, background);
EXTRA_VALUE(GCLineWidth, line_width);
EXTRA_VALUE(GCLineStyle, line_style);
EXTRA_VALUE(GCCapStyle, cap_style);
EXTRA_VALUE(GCJoinStyle, join_style);
EXTRA_VALUE(GCFillStyle, fill_style);
EXTRA_VALUE(GCFillRule, fill_rule);
EXTRA_VALUE(GCTile, tile);
EXTRA_VALUE(GCStipple, stipple);
EXTRA_VALUE(GCTileStipXOrigin, ts_x_origin);
EXTRA_VALUE(GCTileStipYOrigin, ts_y_origin);
EXTRA_VALUE(GCFont, font);
EXTRA_VALUE(GCSubwindowMode, subwindow_mode);
EXTRA_VALUE(GCGraphicsExposures, graphics_exposures);
EXTRA_VALUE(GCClipXOrigin, clip_x_origin);
EXTRA_VALUE(GCClipYOrigin, clip_y_origin);
EXTRA_VALUE(GCClipMask, clip_mask);
EXTRA_VALUE(GCDashOffset, dash_offset);
EXTRA_VALUE(GCDashList, dashes);
EXTRA_VALUE(GCArcMode, arc_mode);
#undef EXTRA_VALUE
xcb_change_gc(conn, gc, mask, value_list);
}
const char WM_COLORMAP_WINDOWS[] = "WM_COLORMAP_WINDOWS";
void xnestWMColormapWindows(xcb_connection_t *conn, xcb_window_t w, xcb_window_t *windows, int count)
{
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(
conn,
xcb_intern_atom(
conn, 0,
sizeof(WM_COLORMAP_WINDOWS)-1,
WM_COLORMAP_WINDOWS),
NULL);
if (!reply)
return;
xcb_icccm_set_wm_colormap_windows_checked(
conn,
w,
reply->atom,
count,
(xcb_window_t*)windows);
free(reply);
}
uint32_t xnestCreateBitmapFromData(
xcb_connection_t *conn,
uint32_t drawable,
const char *data,
uint32_t width,
uint32_t height)
{
uint32_t pix = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_pixmap(conn, 1, pix, drawable, width, height);
uint32_t gc = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_gc(conn, gc, pix, 0, NULL);
const int leftPad = 0;
xcb_put_image(conn,
XYPixmap,
pix,
gc,
width,
height,
0 /* dst_x */,
0 /* dst_y */,
leftPad,
1 /* depth */,
BitmapBytePad(width + leftPad) * height,
(uint8_t*)data);
xcb_free_gc(conn, gc);
return pix;
}
uint32_t xnestCreatePixmapFromBitmapData(
xcb_connection_t *conn,
uint32_t drawable,
const char *data,
uint32_t width,
uint32_t height,
uint32_t fg,
uint32_t bg,
uint16_t depth)
{
uint32_t pix = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_pixmap(conn, depth, pix, drawable, width, height);
uint32_t gc = xcb_generate_id(xnestUpstreamInfo.conn);
xcb_create_gc(conn, gc, pix, 0, NULL);
XnGCValues gcv = {
.foreground = fg,
.background = bg
};
xnChangeGC(conn, gc, gcv, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND);
const int leftPad = 0;
xcb_put_image(conn,
XYBitmap,
pix,
gc,
width,
height,
0 /* dst_x */,
0 /* dst_y */,
leftPad,
1 /* depth */,
BitmapBytePad(width + leftPad) * height,
(uint8_t*)data);
xcb_free_gc(conn, gc);
return pix;
}
void xnestSetCommand(
xcb_connection_t *conn,
xcb_window_t window,
char **argv,
int argc)
{
int i = 0, nbytes = 0;
for (i = 0, nbytes = 0; i < argc; i++)
nbytes += strlen(argv[i]) + 1;
if (nbytes >= (2^16) - 1)
return;
char buf[nbytes+1];
char *bp = buf;
/* copy arguments into single buffer */
for (i = 0; i < argc; i++) {
strcpy(bp, argv[i]);
bp += strlen(argv[i]) + 1;
}
xcb_change_property(conn,
XCB_PROP_MODE_REPLACE,
window,
XCB_ATOM_WM_COMMAND,
XCB_ATOM_STRING,
8,
nbytes,
buf);
}
void xnestXkbInit(xcb_connection_t *conn)
{
xcb_generic_error_t *err = NULL;
xcb_xkb_use_extension_reply_t *reply = xcb_xkb_use_extension_reply(
xnestUpstreamInfo.conn,
xcb_xkb_use_extension(
xnestUpstreamInfo.conn,
XCB_XKB_MAJOR_VERSION,
XCB_XKB_MINOR_VERSION),
&err);
if (err) {
ErrorF("failed query xkb extension: %d\n", err->error_code);
free(err);
} else {
free(reply);
}
}
#define XkbGBN_AllComponentsMask_2 ( \
XCB_XKB_GBN_DETAIL_TYPES | \
XCB_XKB_GBN_DETAIL_COMPAT_MAP | \
XCB_XKB_GBN_DETAIL_CLIENT_SYMBOLS | \
XCB_XKB_GBN_DETAIL_SERVER_SYMBOLS | \
XCB_XKB_GBN_DETAIL_INDICATOR_MAPS | \
XCB_XKB_GBN_DETAIL_KEY_NAMES | \
XCB_XKB_GBN_DETAIL_GEOMETRY | \
XCB_XKB_GBN_DETAIL_OTHER_NAMES)
int xnestXkbDeviceId(xcb_connection_t *conn)
{
int device_id = -1;
uint8_t xlen[6] = { 0 };
xcb_generic_error_t *err = NULL;
xcb_xkb_get_kbd_by_name_reply_t *reply = xcb_xkb_get_kbd_by_name_reply(
xnestUpstreamInfo.conn,
xcb_xkb_get_kbd_by_name_2(
xnestUpstreamInfo.conn,
XCB_XKB_ID_USE_CORE_KBD,
XkbGBN_AllComponentsMask_2,
XkbGBN_AllComponentsMask_2,
0,
sizeof(xlen),
xlen),
&err);
if (err) {
ErrorF("failed retrieving core keyboard: %d\n", err->error_code);
free(err);
return -1;
}
if (!reply) {
ErrorF("failed retrieving core keyboard: no reply");
return -1;
}
device_id = reply->deviceID;
free(reply);
return device_id;
}
xcb_get_keyboard_mapping_reply_t *xnestGetKeyboardMapping(
xcb_connection_t *conn,
int min_keycode,
int count
) {
xcb_generic_error_t *err= NULL;
xcb_get_keyboard_mapping_reply_t * reply = xcb_get_keyboard_mapping_reply(
xnestUpstreamInfo.conn,
xcb_get_keyboard_mapping(conn, min_keycode, count),
&err);
if (err) {
ErrorF("Couldn't get keyboard mapping: %d\n", err->error_code);
free(err);
}
return reply;
}
void xnestGetPointerControl(
xcb_connection_t *conn,
int *acc_num,
int *acc_den,
int *threshold)
{
xcb_generic_error_t *err = NULL;
xcb_get_pointer_control_reply_t *reply = xcb_get_pointer_control_reply(
xnestUpstreamInfo.conn,
xcb_get_pointer_control(xnestUpstreamInfo.conn),
&err);
if (err) {
ErrorF("error retrieving pointer control data: %d\n", err->error_code);
free(err);
}
if (!reply) {
ErrorF("error retrieving pointer control data: no reply\n");
return;
}
*acc_num = reply->acceleration_numerator;
*acc_den = reply->acceleration_denominator;
*threshold = reply->threshold;
free(reply);
}
xRectangle xnestGetGeometry(xcb_connection_t *conn, uint32_t window)
{
xcb_generic_error_t *err = NULL;
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(
xnestUpstreamInfo.conn,
xcb_get_geometry(xnestUpstreamInfo.conn, window),
&err);
if (err) {
ErrorF("failed getting window attributes for %d: %d\n", window, err->error_code);
free(err);
return (xRectangle) { 0 };
}
if (!reply) {
ErrorF("failed getting window attributes for %d: no reply\n", window);
return (xRectangle) { 0 };
}
return (xRectangle) {
.x = reply->x,
.y = reply->y,
.width = reply->width,
.height = reply->height };
}
static int __readint(const char *str, const char **next)
{
int res = 0, sign = 1;
if (*str=='+')
str++;
else if (*str=='-') {
str++;
sign = -1;
}
for (; (*str>='0') && (*str<='9'); str++)
res = (res * 10) + (*str-'0');
*next = str;
return sign * res;
}
int xnestParseGeometry(const char *string, xRectangle *geometry)
{
int mask = 0;
const char *next;
xRectangle temp = { 0 };
if ((string == NULL) || (*string == '\0')) return 0;
if (*string == '=')
string++; /* ignore possible '=' at beg of geometry spec */
if (*string != '+' && *string != '-' && *string != 'x') {
temp.width = __readint(string, &next);
if (string == next)
return 0;
string = next;
mask |= XCB_CONFIG_WINDOW_WIDTH;
}
if (*string == 'x' || *string == 'X') {
string++;
temp.height = __readint(string, &next);
if (string == next)
return 0;
string = next;
mask |= XCB_CONFIG_WINDOW_HEIGHT;
}
if ((*string == '+') || (*string== '-')) {
if (*string== '-') {
string++;
temp.x = -__readint(string, &next);
if (string == next)
return 0;
string = next;
}
else
{
string++;
temp.x = __readint(string, &next);
if (string == next)
return 0;
string = next;
}
mask |= XCB_CONFIG_WINDOW_X;
if ((*string == '+') || (*string== '-')) {
if (*string== '-') {
string++;
temp.y = -__readint(string, &next);
if (string == next)
return 0;
string = next;
}
else
{
string++;
temp.y = __readint(string, &next);
if (string == next)
return 0;
string = next;
}
mask |= XCB_CONFIG_WINDOW_Y;
}
}
if (*string != '\0') return 0;
if (mask & XCB_CONFIG_WINDOW_X)
geometry->x = temp.x;
if (mask & XCB_CONFIG_WINDOW_Y)
geometry->y = temp.y;
if (mask & XCB_CONFIG_WINDOW_WIDTH)
geometry->width = temp.width;
if (mask & XCB_CONFIG_WINDOW_HEIGHT)
geometry->height = temp.height;
return mask;
}
uint32_t xnest_visual_map_to_host(VisualID visual)
{
for (int i = 0; i < xnestNumVisualMap; i++) {
if (xnestVisualMap[i].ourXID == visual) {
return xnestVisualMap[i].upstreamVisual->visual_id;
}
}
return XCB_NONE;
}
uint32_t xnestHostVisualToHostCmap(uint32_t upstreamVisual)
{
for (int i = 0; i < xnestNumVisualMap; i++) {
if (xnestVisualMap[i].upstreamVisual->visual_id == upstreamVisual) {
return xnestVisualMap[i].upstreamCMap;
}
}
return XCB_COLORMAP_NONE;
}
uint32_t xnestVisualToHostCmap(uint32_t visual)
{
for (int i = 0; i < xnestNumVisualMap; i++) {
if (xnestVisualMap[i].ourXID == visual) {
return xnestVisualMap[i].upstreamCMap;
}
}
return XCB_COLORMAP_NONE;
}
static inline char XN_CI_NONEXISTCHAR(xcb_charinfo_t *cs)
{
return ((cs->character_width == 0) && \
((cs->right_side_bearing | cs->left_side_bearing | cs->ascent | cs->descent) == 0));
}
#define XN_CI_GET_CHAR_INFO_1D(font,col,def,cs) \
do { \
cs = def; \
if (col >= font->font_reply->min_char_or_byte2 && col <= font->font_reply->max_char_or_byte2) { \
if (font->chars == NULL) { \
cs = &font->font_reply->min_bounds; \
} else { \
cs = (xcb_charinfo_t *)&font->chars[(col - font->font_reply->min_char_or_byte2)]; \
if (XN_CI_NONEXISTCHAR(cs)) cs = def; \
} \
} \
} while (0)
#define XN_CI_GET_CHAR_INFO_2D(font,row,col,def,cs) \
do { \
cs = def; \
if (row >= font->font_reply->min_byte1 && row <= font->font_reply->max_byte1 && \
col >= font->font_reply->min_char_or_byte2 && col <= font->font_reply->max_char_or_byte2) { \
if (font->chars == NULL) { \
cs = &font->font_reply->min_bounds; \
} else { \
cs = (xcb_charinfo_t*)&font->chars[((row - font->font_reply->min_byte1) * \
(font->font_reply->max_char_or_byte2 - \
font->font_reply->min_char_or_byte2 + 1)) + \
(col - font->font_reply->min_char_or_byte2)]; \
if (XN_CI_NONEXISTCHAR(cs)) cs = def; \
} \
} \
} while (0)
#define XN_CI_GET_DEFAULT_INFO_2D(font,cs) \
do { \
unsigned int r = (font->font_reply->default_char >> 8); \
unsigned int c = (font->font_reply->default_char & 0xff); \
XN_CI_GET_CHAR_INFO_2D (font, r, c, NULL, cs); \
} while (0)
#define XN_CI_GET_ROWZERO_CHAR_INFO_2D(font,col,def,cs) \
do { \
cs = def; \
if (font->font_reply->min_byte1 == 0 && \
col >= font->font_reply->min_char_or_byte2 && col <= font->font_reply->max_char_or_byte2) { \
if (font->chars == NULL) { \
cs = &font->font_reply->min_bounds; \
} else { \
cs = (xcb_charinfo_t*)&font->chars[(col - font->font_reply->min_char_or_byte2)]; \
if (XN_CI_NONEXISTCHAR(cs)) cs = def; \
} \
} \
} while (0)
int
xnestTextWidth (
xnestPrivFont *font,
const char *string,
int count)
{
xcb_charinfo_t *def;
if (font->font_reply->max_byte1 == 0)
XN_CI_GET_CHAR_INFO_1D (font, font->font_reply->default_char, NULL, def);
else
XN_CI_GET_DEFAULT_INFO_2D (font, def);
if (def && font->font_reply->min_bounds.character_width == font->font_reply->max_bounds.character_width)
return (font->font_reply->min_bounds.character_width * count);
int width = 0, i = 0;
unsigned char *us;
for (i = 0, us = (unsigned char *) string; i < count; i++, us++) {
unsigned uc = (unsigned) *us;
xcb_charinfo_t *cs;
if (font->font_reply->max_byte1 == 0) {
XN_CI_GET_CHAR_INFO_1D (font, uc, def, cs);
} else {
XN_CI_GET_ROWZERO_CHAR_INFO_2D (font, uc, def, cs);
}
if (cs) width += cs->character_width;
}
return width;
}
int xnestTextWidth16 (xnestPrivFont *font, const uint16_t* str, int count)
{
xcb_charinfo_t *def;
xcb_char2b_t *string = (xcb_char2b_t*)str;
if (font->font_reply->max_byte1 == 0)
XN_CI_GET_CHAR_INFO_1D (font, font->font_reply->default_char, NULL, def);
else
XN_CI_GET_DEFAULT_INFO_2D (font, def);
if (def && font->font_reply->min_bounds.character_width == font->font_reply->max_bounds.character_width)
return (font->font_reply->min_bounds.character_width * count);
int width = 0;
for (int i = 0; i < count; i++, string++) {
xcb_charinfo_t *cs;
unsigned int r = (unsigned int) string->byte1;
unsigned int c = (unsigned int) string->byte2;
if (font->font_reply->max_byte1 == 0) {
unsigned int ind = ((r << 8) | c);
XN_CI_GET_CHAR_INFO_1D (font, ind, def, cs);
} else {
XN_CI_GET_CHAR_INFO_2D (font, r, c, def, cs);
}
if (cs) width += cs->character_width;
}
return width;
}

90
hw/xnest/xkb.c Normal file
View File

@ -0,0 +1,90 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h> /* for offsetof() */
#include <xcb/xcbext.h>
#include <xcb/xkb.h>
#include <xcb/xproto.h>
#include "xnest-xkb.h"
xcb_xkb_get_kbd_by_name_cookie_t
xcb_xkb_get_kbd_by_name_2 (xcb_connection_t *c,
xcb_xkb_device_spec_t deviceSpec,
uint16_t need,
uint16_t want,
uint8_t load,
uint32_t data_len,
const uint8_t *data)
{
static const xcb_protocol_request_t xcb_req = {
.count = 4,
.ext = &xcb_xkb_id,
.opcode = XCB_XKB_GET_KBD_BY_NAME,
.isvoid = 0
};
struct iovec xcb_parts[6];
xcb_xkb_get_kbd_by_name_cookie_t xcb_ret;
xcb_xkb_get_kbd_by_name_request_t xcb_out;
xcb_out.deviceSpec = deviceSpec;
xcb_out.need = need;
xcb_out.want = want;
xcb_out.load = load;
xcb_out.pad0 = 0;
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
/* uint8_t data */
xcb_parts[4].iov_base = (char *) data;
xcb_parts[4].iov_len = data_len * sizeof(uint8_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
xcb_xkb_get_kbd_by_name_cookie_t
xcb_xkb_get_kbd_by_name_2_unchecked (xcb_connection_t *c,
xcb_xkb_device_spec_t deviceSpec,
uint16_t need,
uint16_t want,
uint8_t load,
uint32_t data_len,
const uint8_t *data)
{
static const xcb_protocol_request_t xcb_req = {
.count = 4,
.ext = &xcb_xkb_id,
.opcode = XCB_XKB_GET_KBD_BY_NAME,
.isvoid = 0
};
struct iovec xcb_parts[6];
xcb_xkb_get_kbd_by_name_cookie_t xcb_ret;
xcb_xkb_get_kbd_by_name_request_t xcb_out;
xcb_out.deviceSpec = deviceSpec;
xcb_out.need = need;
xcb_out.want = want;
xcb_out.load = load;
xcb_out.pad0 = 0;
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
/* uint8_t data */
xcb_parts[4].iov_base = (char *) data;
xcb_parts[4].iov_len = data_len * sizeof(uint8_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}

157
hw/xnest/xnest-xcb.h Normal file
View File

@ -0,0 +1,157 @@
/* SPDX-License-Identifier: MIT OR X11
*
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
*/
#ifndef __XNEST__XCB_H
#define __XNEST__XCB_H
#include <xcb/xcb.h>
#include "include/list.h"
typedef struct {
struct xorg_list entry;
xcb_generic_event_t *event;
} xnestEventQueue;
typedef struct {
xcb_connection_t *conn;
int screenId;
const xcb_screen_t *screenInfo;
const xcb_setup_t *setup;
xnestEventQueue eventQueue;
} xnestUpstreamInfoRec;
extern xnestUpstreamInfoRec xnestUpstreamInfo;
/* connect to upstream X server */
Bool xnest_upstream_setup(const char* displayName);
/* retrieve upstream GC XID for our xserver GC */
uint32_t xnestUpstreamGC(GCPtr pGC);
typedef struct {
uint32_t background_pixmap;
uint32_t background_pixel;
uint32_t border_pixmap;
uint32_t border_pixel;
uint16_t bit_gravity;
uint16_t win_gravity;
uint16_t backing_store;
uint32_t backing_planes;
uint32_t backing_pixel;
Bool save_under;
uint32_t event_mask;
uint32_t do_not_propagate_mask;
Bool override_redirect;
uint32_t colormap;
uint32_t cursor;
} XnSetWindowAttr;
void xnest_encode_window_attr(XnSetWindowAttr attr, uint32_t mask, uint32_t *values);
typedef struct {
int x, y;
int width, height;
int border_width;
uint32_t sibling;
int stack_mode;
} XnWindowChanges;
void xnest_configure_window(xcb_connection_t *conn, uint32_t window, uint32_t mask, XnWindowChanges values);
typedef struct {
int key_click_percent;
int bell_percent;
int bell_pitch;
int bell_duration;
int led;
int led_mode;
int key;
int auto_repeat_mode;
} XnKeyboardControl;
typedef struct {
xcb_visualtype_t *upstreamVisual;
xcb_depth_t *upstreamDepth;
xcb_colormap_t upstreamCMap;
uint32_t ourXID;
VisualPtr ourVisual;
} XnestVisualRec;
extern XnestVisualRec *xnestVisualMap;
extern int xnestNumVisualMap;
void xnestEncodeKeyboardControl(XnKeyboardControl ctrl, long mask, uint32_t *value);
typedef struct {
int function; /* logical operation */
unsigned long plane_mask;/* plane mask */
unsigned long foreground;/* foreground pixel */
unsigned long background;/* background pixel */
int line_width; /* line width */
int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */
int cap_style; /* CapNotLast, CapButt,
CapRound, CapProjecting */
int join_style; /* JoinMiter, JoinRound, JoinBevel */
int fill_style; /* FillSolid, FillTiled,
FillStippled, FillOpaqueStippled */
int fill_rule; /* EvenOddRule, WindingRule */
int arc_mode; /* ArcChord, ArcPieSlice */
xcb_pixmap_t tile; /* tile pixmap for tiling operations */
xcb_pixmap_t stipple; /* stipple 1 plane pixmap for stippling */
int ts_x_origin; /* offset for tile or stipple operations */
int ts_y_origin;
xcb_font_t font; /* default text font for text operations */
int subwindow_mode; /* ClipByChildren, IncludeInferiors */
Bool graphics_exposures;/* boolean, should exposures be generated */
int clip_x_origin; /* origin for clipping */
int clip_y_origin;
xcb_pixmap_t clip_mask; /* bitmap clipping; other calls for rects */
int dash_offset; /* patterned/dashed line information */
char dashes;
} XnGCValues;
void xnChangeGC(xcb_connection_t *conn, uint32_t gc, XnGCValues gcval, uint32_t mask);
void xnestWMColormapWindows(xcb_connection_t *conn, xcb_window_t w, xcb_window_t *windows, int count);
uint32_t xnestCreateBitmapFromData(xcb_connection_t *conn, uint32_t drawable,
const char *data, uint32_t width, uint32_t height);
uint32_t xnestCreatePixmapFromBitmapData(xcb_connection_t *conn, uint32_t drawable,
const char *data, uint32_t width, uint32_t height,
uint32_t fg, uint32_t bg, uint16_t depth);
void xnestSetCommand(xcb_connection_t *conn, xcb_window_t window, char ** argv, int argc);
void xnestXkbInit(xcb_connection_t *conn);
int xnestXkbDeviceId(xcb_connection_t *conn);
xcb_get_keyboard_mapping_reply_t *xnestGetKeyboardMapping(
xcb_connection_t *conn,
int min_keycode,
int count
);
void xnestGetPointerControl(xcb_connection_t *conn, int *acc_num, int *acc_den, int *threshold);
xRectangle xnestGetGeometry(xcb_connection_t *conn, uint32_t window);
int xnestParseGeometry(const char *string, xRectangle *geometry);
uint32_t xnest_visual_map_to_host(VisualID visual);
uint32_t xnestHostVisualToHostCmap(uint32_t visual);
uint32_t xnestVisualToHostCmap(uint32_t visual);
typedef struct {
xcb_query_font_reply_t *font_reply;
xcb_font_t font_id;
xcb_charinfo_t *chars;
uint16_t chars_len;
} xnestPrivFont;
int xnestTextWidth (xnestPrivFont *font, const char *string, int count);
int xnestTextWidth16 (xnestPrivFont *font, const uint16_t *string, int count);
#endif /* __XNEST__XCB_H */

29
hw/xnest/xnest-xkb.h Normal file
View File

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: MIT OR X11
*
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
*/
#ifndef __XNEST__XKB_H
#define __XNEST__XKB_H
#include <xcb/xcb.h>
#include <xcb/xkb.h>
xcb_xkb_get_kbd_by_name_cookie_t
xcb_xkb_get_kbd_by_name_2 (xcb_connection_t *c,
xcb_xkb_device_spec_t deviceSpec,
uint16_t need,
uint16_t want,
uint8_t load,
uint32_t data_len,
const uint8_t *data);
xcb_xkb_get_kbd_by_name_cookie_t
xcb_xkb_get_kbd_by_name_2_unchecked (xcb_connection_t *c,
xcb_xkb_device_spec_t deviceSpec,
uint16_t need,
uint16_t want,
uint8_t load,
uint32_t data_len,
const uint8_t *data);
#endif /* __XNEST__XKB_H */

View File

@ -245,20 +245,6 @@ endif
## configure Xnest - nesting X server
build_xnest = get_option('xnest') != 'false'
xnest_required = get_option('xnest') == 'true'
xnest_dep = [
dependency('xext', version: xext_req, required: xnest_required),
dependency('x11', required: xnest_required),
dependency('xau', required: xnest_required),
]
if get_option('xnest') == 'auto'
# check for all the deps being found, to handle 'auto' mode.
foreach d: xnest_dep
if not d.found()
build_xnest = false
endif
endforeach
endif
build_xwin = false
if get_option('xwin') == 'auto'