00001
00002
00003 #include <stdio.h>
00004
00005 #include <l1394_XShmImg.h>
00006 #include <l1394_device.h>
00007
00008 namespace L1394_MM{
00009
00010 XShmImg::XShmImg(const int iwidth,const int iheight,const char *title,l1394_converter decoder)
00011 : Window(decoder)
00012 {
00013 width = iwidth;
00014 height = iheight;
00015 is_init = false;
00016 allocate();
00017 setTitle(title);
00018 }
00019 XShmImg::XShmImg(const char *title,l1394_converter decoder)
00020 : Window(decoder)
00021 {
00022 is_init = false;
00023 this->title = title;
00024 width = 0;
00025 height = 0;
00026 }
00027
00028 void XShmImg::start() {
00029 if (getDevice() != NULL){
00030 if (!is_init) {
00031 width = getDevice()->getFrameWidth();
00032 height = getDevice()->getFrameHeight();
00033 allocate();
00034 }
00035 Window::start();
00036 }
00037 }
00038 void XShmImg::allocate(){
00039
00040 display = XOpenDisplay(NULL);
00041
00042 if(!display) {
00043 message->errorStream()<< "XShmImg: cannot open display" << endl;
00044 return;
00045 }
00046
00047
00048 if(!XShmQueryExtension(display)) {
00049 message->errorStream() << "XShmImg: no SHM extension available" << endl;
00050 return;
00051 }
00052
00053
00054 win = XCreateSimpleWindow(display, DefaultRootWindow(display),
00055 0, 0, width, height, 0, 1, 0);
00056
00057
00058 XMapWindow(display, win);
00059
00060 depth = DefaultDepth(display, DefaultScreen(display));
00061
00062 XSizeHints hints;
00063
00064 hints.flags = PSize | PMaxSize | PMinSize;
00065 hints.width = hints.max_width = hints.min_width = width;
00066 hints.height = hints.max_height = hints.min_height = height;
00067
00068 XSetStandardProperties(display, win, title, NULL, None,
00069 NULL, 0, &hints);
00070
00071 gc = XCreateGC(display, win, 0, NULL);
00072 XSetFunction(display, gc, GXcopy);
00073
00074
00075 image = XShmCreateImage(display,
00076 DefaultVisual(display, DefaultScreen(display)),
00077 depth,
00078 ZPixmap,
00079 NULL,
00080 &Shminfo,
00081 width,
00082 height);
00083
00084 if(!image) {
00085 message->errorStream() << "XShmImg: cannot create XShmImage" << endl;
00086 return;
00087 }
00088
00089
00090 Shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height,
00091 IPC_CREAT|0777);
00092
00093
00094
00095 if(Shminfo.shmid < 0) {
00096 message->errorStream() << "XShmImg: cannot get memory" << endl;
00097 return;
00098 }
00099
00100 image->data = reinterpret_cast<char*>(shmat(Shminfo.shmid, 0, 0));
00101 Shminfo.shmaddr = image->data;
00102 Shminfo.readOnly = False;
00103
00104 if(!XShmAttach(display, &Shminfo)) {
00105 message->errorStream() << "XShmImg: cannot get SHM"<< endl;
00106 return;
00107 }
00108
00109 shmctl(Shminfo.shmid, IPC_RMID, 0);
00110 XSync(display, False);
00111 is_init = true;
00112 }
00113
00114 XShmImg::~XShmImg(){
00115 stop();
00116
00117 XShmDetach(display, &Shminfo);
00118 XDestroyImage(image);
00119 shmdt(Shminfo.shmaddr);
00120
00121 XFreeGC(display, gc);
00122 XCloseDisplay(display);
00123 }
00124
00125 unsigned char *XShmImg::getBuffer() const
00126 {
00127 if (is_init)
00128 return (unsigned char*)(image->data);
00129 return NULL;
00130 }
00131
00132 void XShmImg::update()
00133 {
00134 XShmPutImage(display, win, gc, image, 0, 0, 0, 0, width, height, False);
00135 XSync(display, False);
00136 }
00137
00138 void XShmImg::setTitle(const char *title)
00139 {
00140 this->title = title;
00141 XStoreName(display, win, title);
00142 XSync(display, False);
00143 }
00144
00145 void XShmImg::nodeDisabled(const L1394::Node* )
00146 {
00147 stop();
00148 }
00149
00150 void XShmImg::nodeDestroy(const L1394::Node* node)
00151 {
00152 if (getDevice()->getParentNode() == node)
00153 {
00154 stop();
00155 disconnect();
00156 delete this;
00157 }
00158 else
00159 message->errorStream() << "XShmImg > Internal Error in nodeDestroy" << endl;
00160 }
00161
00162
00163 }
00164
00165
00166 #ifdef _TEST
00167
00168 int main()
00169 {
00170 XShmImg img(640, 480, "myshmwin");
00171 XShmImg img2(320, 200, "myshmwin2");
00172
00173
00174 for(int x=10; x<630; x++)
00175 for(int y=10; y<470 ; y++)
00176 img.SetPixel(x, y, 100, 100, 100);
00177
00178 for(int x=10; x<310; x++)
00179 for(int y=10; y< 190; y++)
00180 img2.SetPixel(x, y, 100, 150, 30);
00181
00182 img2.Update();
00183
00184 img.Update();
00185
00186 getchar();
00187
00188 img.SetTitle("win2 shm");
00189
00190 getchar();
00191 }
00192
00193 #endif
00194
00195
00196
00197 #ifdef _TEST2
00198 #include <sys/times.h>
00199 int main()
00200 {
00201
00202
00203 XShmImg img(640, 480, "myshmwin");
00204
00205 char *data = img.GetBuffer();
00206
00207 for(int x=10; x<630; x++)
00208 for(int y=10; y<470 ; y++)
00209 img.SetPixel(x, y, 100, 100, 100);
00210
00211 for(int i=0; i<100; i++)
00212 {
00213 static time_t end, start;
00214 float fsecs;
00215 char buf[256];
00216
00217 sprintf(buf, "XShmImg: %3.02g frames/sec\n", 1./fsecs);
00218 printf("XShmImg: %3.02g frames/sec\n", 1./fsecs);
00219
00220 img.Update();
00221 img.SetTitle(buf);
00222
00223 for(int x=10; x<630; x++)
00224 for(int y=10; y<470 ; y++)
00225 img.SetPixel(x, y, 100, 100, 100);
00226
00227
00228
00229
00230 end = times(NULL);
00231 fsecs = (end-start)/100.0;
00232 start = end;
00233 }
00234
00235 }
00236
00237 #endif
00238