150 lines
4.8 KiB
C++
150 lines
4.8 KiB
C++
// Filename: subprocessWindowBuffer.h
|
|
// Created by: drose (11Jul09)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
//
|
|
// All use of this software is subject to the terms of the revised BSD
|
|
// license. You should have received a copy of this license along
|
|
// with this source code in a file named "LICENSE."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef SUBPROCESSWINDOWBUFFER_H
|
|
#define SUBPROCESSWINDOWBUFFER_H
|
|
|
|
#include <stdio.h> // perror
|
|
#include <assert.h>
|
|
#include <string>
|
|
using namespace std;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Class : SubprocessWindowBuffer
|
|
// Description : This is a special class that is designed to faciliate
|
|
// SubprocessWindow. It's intended to be allocated
|
|
// within a shared memory buffer, and it contains space
|
|
// for a framebuffer image to be stored for transferring
|
|
// between processes, as well as appropriate
|
|
// synchronization primitives.
|
|
//
|
|
// It's designed to be compiled outside of Panda, so
|
|
// that code that doesn't link with Panda (in
|
|
// particular, the Panda3D plugin core API) may still
|
|
// link with this and use it.
|
|
//
|
|
// At the moment, and maybe indefinitely, it is only
|
|
// compiled on OSX, and only when we are building
|
|
// support for the plugin; because it is only needed
|
|
// then.
|
|
////////////////////////////////////////////////////////////////////
|
|
class SubprocessWindowBuffer {
|
|
private:
|
|
void *operator new(size_t, void *addr);
|
|
SubprocessWindowBuffer(int x_size, int y_size);
|
|
SubprocessWindowBuffer(const SubprocessWindowBuffer ©);
|
|
~SubprocessWindowBuffer();
|
|
|
|
public:
|
|
static SubprocessWindowBuffer *new_buffer(int &fd, size_t &mmap_size,
|
|
string &filename,
|
|
int x_size, int y_size);
|
|
static void destroy_buffer(int fd, size_t mmap_size,
|
|
const string &filename,
|
|
SubprocessWindowBuffer *buffer);
|
|
|
|
static SubprocessWindowBuffer *open_buffer(int &fd, size_t &mmap_size,
|
|
const string &filename);
|
|
static void close_buffer(int fd, size_t mmap_size,
|
|
const string &filename,
|
|
SubprocessWindowBuffer *buffer);
|
|
|
|
bool verify_magic_number() const;
|
|
|
|
inline int get_x_size() const;
|
|
inline int get_y_size() const;
|
|
inline size_t get_row_size() const;
|
|
inline size_t get_framebuffer_size() const;
|
|
|
|
inline bool ready_for_read() const;
|
|
inline bool ready_for_write() const;
|
|
|
|
inline const void *open_read_framebuffer();
|
|
inline void close_read_framebuffer();
|
|
inline void *open_write_framebuffer();
|
|
inline void close_write_framebuffer();
|
|
|
|
enum EventSource {
|
|
ES_none,
|
|
ES_mouse,
|
|
ES_keyboard
|
|
};
|
|
|
|
enum EventType {
|
|
ET_none,
|
|
ET_button_down,
|
|
ET_button_up,
|
|
ET_button_again, // if supported
|
|
};
|
|
|
|
enum EventFlags {
|
|
EF_has_mouse = 0x0001,
|
|
EF_mouse_position = 0x0002,
|
|
EF_shift_held = 0x0004,
|
|
EF_control_held = 0x0008,
|
|
EF_alt_held = 0x0010,
|
|
EF_meta_held = 0x0020,
|
|
EF_caps_lock = 0x0040,
|
|
};
|
|
|
|
class Event {
|
|
public:
|
|
EventSource _source;
|
|
int _code; // mouse button, or os-specific keycode.
|
|
EventType _type;
|
|
int _x, _y; // position of mouse at the time of the event, if EF_mouse_position is set
|
|
unsigned int _flags;
|
|
};
|
|
|
|
inline bool add_event(const Event &event);
|
|
inline bool has_event() const;
|
|
inline bool get_event(Event &event);
|
|
|
|
private:
|
|
// The first thing we store in the buffer is a magic number, so we
|
|
// don't accidentally memory-map the wrong file and attempt to treat
|
|
// it as a window buffer.
|
|
enum { magic_number_length = 8 };
|
|
static const char _magic_number[magic_number_length];
|
|
char _this_magic[magic_number_length];
|
|
|
|
// Then we have the required size of the entire structure, including
|
|
// its data blocks.
|
|
size_t _mmap_size;
|
|
|
|
// Then some other important parameters.
|
|
int _x_size, _y_size;
|
|
size_t _row_size;
|
|
size_t _framebuffer_size;
|
|
|
|
// A circular queue of events.
|
|
enum { max_events = 64 };
|
|
int _event_in; // next slot to write an event to
|
|
int _event_out; // next slot to read an event from
|
|
Event _events[max_events];
|
|
// The queue is empty when _event_in == _event_out.
|
|
// It is full when _event_in == _event_out - 1, circularly.
|
|
|
|
// These sequence numbers are incremented as frames are written and
|
|
// read.
|
|
int _last_written;
|
|
int _last_read;
|
|
|
|
// The framebuffer data begins immediately at the end of this class.
|
|
};
|
|
|
|
#include "subprocessWindowBuffer.I"
|
|
|
|
#endif
|