summaryrefslogtreecommitdiffstats
path: root/app/surface/transport_dib_linux.cc
diff options
context:
space:
mode:
authorpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-19 14:01:33 +0000
committerpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-19 14:01:33 +0000
commit6c077af5c79a85d64e4b4363b8d0e29bb16543db (patch)
tree160a0dc0eb5b39a3c302655a287d1594d4ccf58e /app/surface/transport_dib_linux.cc
parent9bb2d8b4792cbf769d744fd972da2d94e9fa9647 (diff)
downloadchromium_src-6c077af5c79a85d64e4b4363b8d0e29bb16543db.zip
chromium_src-6c077af5c79a85d64e4b4363b8d0e29bb16543db.tar.gz
chromium_src-6c077af5c79a85d64e4b4363b8d0e29bb16543db.tar.bz2
Remove dependency from webkit on chrome/common by moving files to src/app.
BUG=37985 TEST=no functional change. Review URL: http://codereview.chromium.org/1060001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42101 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app/surface/transport_dib_linux.cc')
-rw-r--r--app/surface/transport_dib_linux.cc113
1 files changed, 113 insertions, 0 deletions
diff --git a/app/surface/transport_dib_linux.cc b/app/surface/transport_dib_linux.cc
new file mode 100644
index 0000000..6c41a0c
--- /dev/null
+++ b/app/surface/transport_dib_linux.cc
@@ -0,0 +1,113 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include "app/surface/transport_dib.h"
+#include "app/x11_util.h"
+#include "base/logging.h"
+#include "gfx/size.h"
+#include "skia/ext/platform_canvas.h"
+
+// The shmat system call uses this as it's invalid return address
+static void *const kInvalidAddress = (void*) -1;
+
+TransportDIB::TransportDIB()
+ : key_(-1),
+ address_(kInvalidAddress),
+ x_shm_(0),
+ display_(NULL),
+ size_(0) {
+}
+
+TransportDIB::~TransportDIB() {
+ if (address_ != kInvalidAddress) {
+ shmdt(address_);
+ address_ = kInvalidAddress;
+ }
+
+ if (x_shm_) {
+ DCHECK(display_);
+ x11_util::DetachSharedMemory(display_, x_shm_);
+ }
+}
+
+// static
+TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) {
+ // We use a mode of 0666 since the X server won't attach to memory which is
+ // 0600 since it can't know if it (as a root process) is being asked to map
+ // someone else's private shared memory region.
+ const int shmkey = shmget(IPC_PRIVATE, size, 0666);
+ if (shmkey == -1) {
+ DLOG(ERROR) << "Failed to create SysV shared memory region"
+ << " errno:" << errno;
+ return NULL;
+ }
+
+ void* address = shmat(shmkey, NULL /* desired address */, 0 /* flags */);
+ // Here we mark the shared memory for deletion. Since we attached it in the
+ // line above, it doesn't actually get deleted but, if we crash, this means
+ // that the kernel will automatically clean it up for us.
+ shmctl(shmkey, IPC_RMID, 0);
+ if (address == kInvalidAddress)
+ return NULL;
+
+ TransportDIB* dib = new TransportDIB;
+
+ dib->key_ = shmkey;
+ dib->address_ = address;
+ dib->size_ = size;
+ return dib;
+}
+
+TransportDIB* TransportDIB::Map(Handle shmkey) {
+ struct shmid_ds shmst;
+ if (shmctl(shmkey, IPC_STAT, &shmst) == -1)
+ return NULL;
+
+ void* address = shmat(shmkey, NULL /* desired address */, 0 /* flags */);
+ if (address == kInvalidAddress)
+ return NULL;
+
+ TransportDIB* dib = new TransportDIB;
+
+ dib->address_ = address;
+ dib->size_ = shmst.shm_segsz;
+ dib->key_ = shmkey;
+ return dib;
+}
+
+bool TransportDIB::is_valid(Handle dib) {
+ return dib >= 0;
+}
+
+skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) {
+ return new skia::PlatformCanvas(w, h, true,
+ reinterpret_cast<uint8_t*>(memory()));
+}
+
+void* TransportDIB::memory() const {
+ DCHECK_NE(address_, kInvalidAddress);
+ return address_;
+}
+
+TransportDIB::Id TransportDIB::id() const {
+ return key_;
+}
+
+TransportDIB::Handle TransportDIB::handle() const {
+ return key_;
+}
+
+XID TransportDIB::MapToX(Display* display) {
+ if (!x_shm_) {
+ x_shm_ = x11_util::AttachSharedMemory(display, key_);
+ display_ = display;
+ }
+
+ return x_shm_;
+}