Panda3D
|
00001 // Filename: subprocessWindowBuffer.h 00002 // Created by: drose (11Jul09) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef SUBPROCESSWINDOWBUFFER_H 00016 #define SUBPROCESSWINDOWBUFFER_H 00017 00018 #include <stdio.h> // perror 00019 #include <assert.h> 00020 #include <string> 00021 using namespace std; 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Class : SubprocessWindowBuffer 00025 // Description : This is a special class that is designed to faciliate 00026 // SubprocessWindow. It's intended to be allocated 00027 // within a shared memory buffer, and it contains space 00028 // for a framebuffer image to be stored for transferring 00029 // between processes, as well as appropriate 00030 // synchronization primitives. 00031 // 00032 // It's designed to be compiled outside of Panda, so 00033 // that code that doesn't link with Panda (in 00034 // particular, the Panda3D plugin core API) may still 00035 // link with this and use it. 00036 // 00037 // At the moment, and maybe indefinitely, it is only 00038 // compiled on OSX, and only when we are building 00039 // support for the plugin; because it is only needed 00040 // then. 00041 //////////////////////////////////////////////////////////////////// 00042 class SubprocessWindowBuffer { 00043 private: 00044 void *operator new(size_t, void *addr); 00045 SubprocessWindowBuffer(int x_size, int y_size); 00046 SubprocessWindowBuffer(const SubprocessWindowBuffer ©); 00047 ~SubprocessWindowBuffer(); 00048 00049 public: 00050 static SubprocessWindowBuffer *new_buffer(int &fd, size_t &mmap_size, 00051 string &filename, 00052 int x_size, int y_size); 00053 static void destroy_buffer(int fd, size_t mmap_size, 00054 const string &filename, 00055 SubprocessWindowBuffer *buffer); 00056 00057 static SubprocessWindowBuffer *open_buffer(int &fd, size_t &mmap_size, 00058 const string &filename); 00059 static void close_buffer(int fd, size_t mmap_size, 00060 const string &filename, 00061 SubprocessWindowBuffer *buffer); 00062 00063 bool verify_magic_number() const; 00064 00065 inline int get_x_size() const; 00066 inline int get_y_size() const; 00067 inline size_t get_row_size() const; 00068 inline size_t get_framebuffer_size() const; 00069 00070 inline bool ready_for_read() const; 00071 inline bool ready_for_write() const; 00072 00073 inline const void *open_read_framebuffer(); 00074 inline void close_read_framebuffer(); 00075 inline void *open_write_framebuffer(); 00076 inline void close_write_framebuffer(); 00077 00078 enum EventSource { 00079 ES_none, 00080 ES_mouse, 00081 ES_keyboard 00082 }; 00083 00084 enum EventType { 00085 ET_none, 00086 ET_button_down, 00087 ET_button_up, 00088 ET_button_again, // if supported 00089 }; 00090 00091 enum EventFlags { 00092 EF_has_mouse = 0x0001, 00093 EF_mouse_position = 0x0002, 00094 EF_shift_held = 0x0004, 00095 EF_control_held = 0x0008, 00096 EF_alt_held = 0x0010, 00097 EF_meta_held = 0x0020, 00098 EF_caps_lock = 0x0040, 00099 }; 00100 00101 class Event { 00102 public: 00103 EventSource _source; 00104 int _code; // mouse button, or os-specific keycode. 00105 EventType _type; 00106 int _x, _y; // position of mouse at the time of the event, if EF_mouse_position is set 00107 unsigned int _flags; 00108 }; 00109 00110 inline bool add_event(const Event &event); 00111 inline bool has_event() const; 00112 inline bool get_event(Event &event); 00113 00114 private: 00115 // The first thing we store in the buffer is a magic number, so we 00116 // don't accidentally memory-map the wrong file and attempt to treat 00117 // it as a window buffer. 00118 enum { magic_number_length = 8 }; 00119 static const char _magic_number[magic_number_length]; 00120 char _this_magic[magic_number_length]; 00121 00122 // Then we have the required size of the entire structure, including 00123 // its data blocks. 00124 size_t _mmap_size; 00125 00126 // Then some other important parameters. 00127 int _x_size, _y_size; 00128 size_t _row_size; 00129 size_t _framebuffer_size; 00130 00131 // A circular queue of events. 00132 enum { max_events = 64 }; 00133 int _event_in; // next slot to write an event to 00134 int _event_out; // next slot to read an event from 00135 Event _events[max_events]; 00136 // The queue is empty when _event_in == _event_out. 00137 // It is full when _event_in == _event_out - 1, circularly. 00138 00139 // These sequence numbers are incremented as frames are written and 00140 // read. 00141 int _last_written; 00142 int _last_read; 00143 00144 // The framebuffer data begins immediately at the end of this class. 00145 }; 00146 00147 #include "subprocessWindowBuffer.I" 00148 00149 #endif