Panda3D

subprocessWindowBuffer.h

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 &copy);
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
 All Classes Functions Variables Enumerations