File indexing completed on 2024-11-10 04:56:36
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de> 0006 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 // own 0011 #include "x11_standalone_non_composited_outline.h" 0012 // KWin libs 0013 #include "../common/kwinxrenderutils.h" 0014 // xcb 0015 #include <xcb/render.h> 0016 0017 namespace KWin 0018 { 0019 0020 NonCompositedOutlineVisual::NonCompositedOutlineVisual(Outline *outline) 0021 : OutlineVisual(outline) 0022 , m_initialized(false) 0023 { 0024 } 0025 0026 NonCompositedOutlineVisual::~NonCompositedOutlineVisual() 0027 { 0028 } 0029 0030 void NonCompositedOutlineVisual::show() 0031 { 0032 if (!m_initialized) { 0033 const QRect geo(0, 0, 1, 1); 0034 const uint32_t values[] = {true}; 0035 // TODO: use template variant 0036 m_leftOutline.create(geo, XCB_CW_OVERRIDE_REDIRECT, values); 0037 m_rightOutline.create(geo, XCB_CW_OVERRIDE_REDIRECT, values); 0038 m_topOutline.create(geo, XCB_CW_OVERRIDE_REDIRECT, values); 0039 m_bottomOutline.create(geo, XCB_CW_OVERRIDE_REDIRECT, values); 0040 m_initialized = true; 0041 } 0042 0043 const int defaultDepth = Xcb::defaultDepth(); 0044 0045 const QRect &outlineGeometry = m_outline->geometry(); 0046 // left/right parts are between top/bottom, they don't reach as far as the corners 0047 const uint16_t verticalWidth = 5; 0048 const uint16_t verticalHeight = outlineGeometry.height() - 10; 0049 const uint16_t horizontalWidth = outlineGeometry.width(); 0050 const uint horizontalHeight = 5; 0051 m_leftOutline.setGeometry(outlineGeometry.x(), outlineGeometry.y() + 5, verticalWidth, verticalHeight); 0052 m_rightOutline.setGeometry(outlineGeometry.x() + outlineGeometry.width() - 5, outlineGeometry.y() + 5, verticalWidth, verticalHeight); 0053 m_topOutline.setGeometry(outlineGeometry.x(), outlineGeometry.y(), horizontalWidth, horizontalHeight); 0054 m_bottomOutline.setGeometry(outlineGeometry.x(), outlineGeometry.y() + outlineGeometry.height() - 5, horizontalWidth, horizontalHeight); 0055 0056 const xcb_render_color_t white = {0xffff, 0xffff, 0xffff, 0xffff}; 0057 QColor qGray(Qt::gray); 0058 const xcb_render_color_t gray = { 0059 uint16_t(0xffff * qGray.redF()), 0060 uint16_t(0xffff * qGray.greenF()), 0061 uint16_t(0xffff * qGray.blueF()), 0062 0xffff}; 0063 const xcb_render_color_t black = {0, 0, 0, 0xffff}; 0064 { 0065 xcb_pixmap_t xpix = xcb_generate_id(connection()); 0066 xcb_create_pixmap(connection(), defaultDepth, xpix, rootWindow(), verticalWidth, verticalHeight); 0067 XRenderPicture pic(xpix, defaultDepth); 0068 0069 xcb_rectangle_t rect = {0, 0, 5, verticalHeight}; 0070 xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, white, 1, &rect); 0071 rect.x = 1; 0072 rect.width = 3; 0073 xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, gray, 1, &rect); 0074 rect.x = 2; 0075 rect.width = 1; 0076 xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, black, 1, &rect); 0077 0078 m_leftOutline.setBackgroundPixmap(xpix); 0079 m_rightOutline.setBackgroundPixmap(xpix); 0080 // According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed. 0081 xcb_free_pixmap(connection(), xpix); 0082 } 0083 { 0084 xcb_pixmap_t xpix = xcb_generate_id(connection()); 0085 xcb_create_pixmap(connection(), defaultDepth, xpix, rootWindow(), horizontalWidth, horizontalHeight); 0086 XRenderPicture pic(xpix, defaultDepth); 0087 0088 xcb_rectangle_t rect = {0, 0, horizontalWidth, horizontalHeight}; 0089 xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, white, 1, &rect); 0090 xcb_rectangle_t grayRects[] = { 0091 {1, 1, uint16_t(horizontalWidth - 2), 3}, 0092 {1, 4, 3, 1}, 0093 {int16_t(horizontalWidth - 4), 4, 3, 1}}; 0094 xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, gray, 3, grayRects); 0095 xcb_rectangle_t blackRects[] = { 0096 {2, 2, uint16_t(horizontalWidth - 4), 1}, 0097 {2, 3, 1, 2}, 0098 {int16_t(horizontalWidth - 3), 3, 1, 2}}; 0099 xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, black, 3, blackRects); 0100 m_topOutline.setBackgroundPixmap(xpix); 0101 // According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed. 0102 xcb_free_pixmap(connection(), xpix); 0103 } 0104 { 0105 xcb_pixmap_t xpix = xcb_generate_id(connection()); 0106 xcb_create_pixmap(connection(), defaultDepth, xpix, rootWindow(), outlineGeometry.width(), 5); 0107 XRenderPicture pic(xpix, defaultDepth); 0108 0109 xcb_rectangle_t rect = {0, 0, horizontalWidth, horizontalHeight}; 0110 xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, white, 1, &rect); 0111 xcb_rectangle_t grayRects[] = { 0112 {1, 1, uint16_t(horizontalWidth - 2), 3}, 0113 {1, 0, 3, 1}, 0114 {int16_t(horizontalWidth - 4), 0, 3, 1}}; 0115 xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, gray, 3, grayRects); 0116 xcb_rectangle_t blackRects[] = { 0117 {2, 2, uint16_t(horizontalWidth - 4), 1}, 0118 {2, 0, 1, 2}, 0119 {int16_t(horizontalWidth - 3), 0, 1, 2}}; 0120 xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, black, 3, blackRects); 0121 m_bottomOutline.setBackgroundPixmap(xpix); 0122 // According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed. 0123 xcb_free_pixmap(connection(), xpix); 0124 } 0125 forEachWindow(&Xcb::Window::clear); 0126 forEachWindow(&Xcb::Window::map); 0127 } 0128 0129 void NonCompositedOutlineVisual::hide() 0130 { 0131 forEachWindow(&Xcb::Window::unmap); 0132 } 0133 0134 } // namespace