Views Omnibox: tolerate minor click-to-select-all dragging.
[chromium-blink-merge.git] / ui / gfx / x / x11_types.cc
blob48ce6416b697b32e9e0a6cb3748631ba06294cd2
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/gfx/x/x11_types.h"
7 #include <X11/Xlib.h>
9 #include "base/message_loop/message_loop.h"
11 namespace gfx {
13 XDisplay* GetXDisplay() {
14 return base::MessagePumpForUI::GetDefaultXDisplay();
17 void PutARGBImage(XDisplay* display,
18 void* visual, int depth,
19 XID pixmap, void* pixmap_gc,
20 const uint8* data,
21 int width, int height) {
22 PutARGBImage(display,
23 visual, depth,
24 pixmap, pixmap_gc,
25 data, width, height,
26 0, 0, // src_x, src_y
27 0, 0, // dst_x, dst_y
28 width, height);
31 int BitsPerPixelForPixmapDepth(XDisplay* dpy, int depth) {
32 int count;
33 XPixmapFormatValues* formats = XListPixmapFormats(dpy, &count);
34 if (!formats)
35 return -1;
37 int bits_per_pixel = -1;
38 for (int i = 0; i < count; ++i) {
39 if (formats[i].depth == depth) {
40 bits_per_pixel = formats[i].bits_per_pixel;
41 break;
45 XFree(formats);
46 return bits_per_pixel;
49 void PutARGBImage(XDisplay* display,
50 void* visual, int depth,
51 XID pixmap, void* pixmap_gc,
52 const uint8* data,
53 int data_width, int data_height,
54 int src_x, int src_y,
55 int dst_x, int dst_y,
56 int copy_width, int copy_height) {
57 // TODO(scherkus): potential performance impact... consider passing in as a
58 // parameter.
59 int pixmap_bpp = BitsPerPixelForPixmapDepth(display, depth);
61 XImage image;
62 memset(&image, 0, sizeof(image));
64 image.width = data_width;
65 image.height = data_height;
66 image.format = ZPixmap;
67 image.byte_order = LSBFirst;
68 image.bitmap_unit = 8;
69 image.bitmap_bit_order = LSBFirst;
70 image.depth = depth;
71 image.bits_per_pixel = pixmap_bpp;
72 image.bytes_per_line = data_width * pixmap_bpp / 8;
74 if (pixmap_bpp == 32) {
75 image.red_mask = 0xff0000;
76 image.green_mask = 0xff00;
77 image.blue_mask = 0xff;
79 // If the X server depth is already 32-bits and the color masks match,
80 // then our job is easy.
81 Visual* vis = static_cast<Visual*>(visual);
82 if (image.red_mask == vis->red_mask &&
83 image.green_mask == vis->green_mask &&
84 image.blue_mask == vis->blue_mask) {
85 image.data = const_cast<char*>(reinterpret_cast<const char*>(data));
86 XPutImage(display, pixmap, static_cast<GC>(pixmap_gc), &image,
87 src_x, src_y, dst_x, dst_y,
88 copy_width, copy_height);
89 } else {
90 // Otherwise, we need to shuffle the colors around. Assume red and blue
91 // need to be swapped.
93 // It's possible to use some fancy SSE tricks here, but since this is the
94 // slow path anyway, we do it slowly.
96 uint8_t* bitmap32 =
97 static_cast<uint8_t*>(malloc(4 * data_width * data_height));
98 if (!bitmap32)
99 return;
100 uint8_t* const orig_bitmap32 = bitmap32;
101 const uint32_t* bitmap_in = reinterpret_cast<const uint32_t*>(data);
102 for (int y = 0; y < data_height; ++y) {
103 for (int x = 0; x < data_width; ++x) {
104 const uint32_t pixel = *(bitmap_in++);
105 bitmap32[0] = (pixel >> 16) & 0xff; // Red
106 bitmap32[1] = (pixel >> 8) & 0xff; // Green
107 bitmap32[2] = pixel & 0xff; // Blue
108 bitmap32[3] = (pixel >> 24) & 0xff; // Alpha
109 bitmap32 += 4;
112 image.data = reinterpret_cast<char*>(orig_bitmap32);
113 XPutImage(display, pixmap, static_cast<GC>(pixmap_gc), &image,
114 src_x, src_y, dst_x, dst_y,
115 copy_width, copy_height);
116 free(orig_bitmap32);
118 } else if (pixmap_bpp == 16) {
119 // Some folks have VNC setups which still use 16-bit visuals and VNC
120 // doesn't include Xrender.
122 uint16_t* bitmap16 =
123 static_cast<uint16_t*>(malloc(2 * data_width * data_height));
124 if (!bitmap16)
125 return;
126 uint16_t* const orig_bitmap16 = bitmap16;
127 const uint32_t* bitmap_in = reinterpret_cast<const uint32_t*>(data);
128 for (int y = 0; y < data_height; ++y) {
129 for (int x = 0; x < data_width; ++x) {
130 const uint32_t pixel = *(bitmap_in++);
131 uint16_t out_pixel = ((pixel >> 8) & 0xf800) |
132 ((pixel >> 5) & 0x07e0) |
133 ((pixel >> 3) & 0x001f);
134 *(bitmap16++) = out_pixel;
138 image.data = reinterpret_cast<char*>(orig_bitmap16);
139 image.red_mask = 0xf800;
140 image.green_mask = 0x07e0;
141 image.blue_mask = 0x001f;
143 XPutImage(display, pixmap, static_cast<GC>(pixmap_gc), &image,
144 src_x, src_y, dst_x, dst_y,
145 copy_width, copy_height);
146 free(orig_bitmap16);
147 } else {
148 LOG(FATAL) << "Sorry, we don't support your visual depth without "
149 "Xrender support (depth:" << depth
150 << " bpp:" << pixmap_bpp << ")";
154 } // namespace gfx