// 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 // perror #include #include 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