summaryrefslogtreecommitdiffstats
path: root/x11vnc.c
blob: 135209736fcf006e13848639197ecfff2bebe87c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <X11/Xlib.h>
#include <X11/keysym.h>
#ifndef NO_SHM
#include <X11/extensions/XShm.h>
#include <sys/shm.h>
#endif
#define KEYSYM_H
#include "rfb.h"

int c=0,blockLength = 32;

Bool useSHM =
#ifndef NO_SHM
 TRUE;
XShmSegmentInfo shminfo;
#else
 FALSE;
#endif

void getImage(int bpp,Display *dpy,int xscreen,XImage **i)
{
  if(useSHM && bpp>0) {

    *i = XShmCreateImage( dpy,
			  DefaultVisual( dpy, xscreen ),
			  bpp,
			  ZPixmap,
			  NULL,
			  &shminfo,
			  DisplayWidth(dpy,xscreen),
			  DisplayHeight(dpy,xscreen));
                                  
    shminfo.shmid = shmget( IPC_PRIVATE,
                                 (*i)->bytes_per_line * (*i)->height,
                                 IPC_CREAT | 0777 );
    shminfo.shmaddr = (*i)->data = (char *) shmat( shminfo.shmid, 0, 0 );
    shminfo.readOnly = False;
  
    XShmAttach( dpy, &shminfo );

    XShmGetImage(dpy,RootWindow(dpy,xscreen),*i,0,0,AllPlanes);
  } else {
    *i = XGetImage(dpy,RootWindow(dpy,xscreen),0,0,DisplayWidth(dpy,xscreen),DisplayHeight(dpy,xscreen),
		    AllPlanes,ZPixmap );
  }
}

void checkForImageUpdates(rfbScreenInfoPtr s,char *b)
{
   Bool changed;
   int i,j,k,l,x1,y1;
   for(j=0;j<s->height;j+=blockLength)
     for(i=0;i<s->width;i+=blockLength) {
	y1=j+blockLength; if(y1>s->height) y1=s->height;
	x1=i+blockLength; if(x1>s->width) x1=s->width;
	y1*=s->paddedWidthInBytes;
	x1*=s->bitsPerPixel/8;
	changed=FALSE;
	for(l=j*s->paddedWidthInBytes;!changed&&l<y1;l+=s->paddedWidthInBytes)
	  for(k=i*s->bitsPerPixel/8;k<x1;k++)
	    if(s->frameBuffer[l+k]!=b[l+k]) {
	      //	       fprintf(stderr,"changed: %d, %d\n",k,l);
	       changed=TRUE;
	       goto changed_p;
	    }
	if(changed) {
	   changed_p:
	  for(l+=i*s->bitsPerPixel/8;l<y1;l+=s->paddedWidthInBytes)
	     memcpy(/*b+l,*/s->frameBuffer+l,b+l,x1-i*s->bitsPerPixel/8);
	   rfbMarkRectAsModified(s,i,j,i+blockLength,j+blockLength);
	}
     }
}

int main(int argc,char** argv)
{
  XImage *framebufferImage;
  char *backupImage;
  Display *dpy;
  int xscreen;
  rfbScreenInfoPtr screen;

  dpy = XOpenDisplay("");
  xscreen = DefaultScreen(dpy);

  getImage(0,dpy,xscreen,&framebufferImage);

  screen = rfbGetScreen(&argc,argv,framebufferImage->width,
			framebufferImage->height,
			framebufferImage->bits_per_pixel,
			8,
			framebufferImage->bits_per_pixel/8);
   
  screen->paddedWidthInBytes = framebufferImage->bytes_per_line;

  screen->rfbServerFormat.bitsPerPixel = framebufferImage->bits_per_pixel;
  screen->rfbServerFormat.depth = framebufferImage->depth;
  rfbEndianTest = framebufferImage->bitmap_bit_order != MSBFirst;
  screen->rfbServerFormat.trueColour = TRUE;

  if ( screen->rfbServerFormat.bitsPerPixel == 8 ) {
    screen->rfbServerFormat.redShift = 0;
    screen->rfbServerFormat.greenShift = 2;
    screen->rfbServerFormat.blueShift = 5;
    screen->rfbServerFormat.redMax   = 3;
    screen->rfbServerFormat.greenMax = 7;
    screen->rfbServerFormat.blueMax  = 3;
  } else {
    screen->rfbServerFormat.redShift = 0;
    if ( framebufferImage->red_mask )
      while ( ! ( framebufferImage->red_mask & (1 << screen->rfbServerFormat.redShift) ) )
        screen->rfbServerFormat.redShift++;
    screen->rfbServerFormat.greenShift = 0;
    if ( framebufferImage->green_mask )
      while ( ! ( framebufferImage->green_mask & (1 << screen->rfbServerFormat.greenShift) ) )
        screen->rfbServerFormat.greenShift++;
    screen->rfbServerFormat.blueShift = 0;
    if ( framebufferImage->blue_mask )
      while ( ! ( framebufferImage->blue_mask & (1 << screen->rfbServerFormat.blueShift) ) )
      screen->rfbServerFormat.blueShift++;
    screen->rfbServerFormat.redMax   = framebufferImage->red_mask   >> screen->rfbServerFormat.redShift;
    screen->rfbServerFormat.greenMax = framebufferImage->green_mask >> screen->rfbServerFormat.greenShift;
    screen->rfbServerFormat.blueMax  = framebufferImage->blue_mask  >> screen->rfbServerFormat.blueShift;
  }

  backupImage = malloc(screen->height*screen->paddedWidthInBytes);
  memcpy(backupImage,framebufferImage->data,screen->height*screen->paddedWidthInBytes);
  screen->frameBuffer = backupImage;
  screen->rfbDeferUpdateTime = 50;
  screen->cursor = 0;

  rfbInitServer(screen);
   
  while(1) {
    //fprintf(stderr,"%d\r",c++);
    rfbProcessEvents(screen,-1);
    //if(1 || /*c++>7 &&*/ (!screen->rfbClientHead || !FB_UPDATE_PENDING(screen->rfbClientHead))) {
    //c=0;
    framebufferImage->f.destroy_image(framebufferImage);
    getImage(screen->rfbServerFormat.bitsPerPixel,dpy,xscreen,&framebufferImage);
    checkForImageUpdates(screen,framebufferImage->data);
    //}
    //fprintf(stderr,"%x\n%x\n---\n",screen->frameBuffer,framebufferImage->data);
     //memcpy(screen->frameBuffer,framebufferImage->data,screen->height*screen->paddedWidthInBytes);
   rfbMarkRectAsModified(screen,0,0,screen->width,screen->height);
#if 0
       {
	  int i,j,r,g,b;
	  FILE* f=fopen("test.pnm","wb");
	  fprintf(f,"P6\n%d %d\n255\n",screen->width,screen->height);
	  for(j=0;j<screen->height;j++)
	    for(i=0;i<screen->width;i++) {
	      //r=screen->frameBuffer[j*screen->paddedWidthInBytes+i*2];
	      r=framebufferImage->data[j*screen->paddedWidthInBytes+i*2];
	       fputc(((r>>screen->rfbServerFormat.redShift)&screen->rfbServerFormat.redMax)*255/screen->rfbServerFormat.redMax,f);
	       fputc(((r>>screen->rfbServerFormat.greenShift)&screen->rfbServerFormat.greenMax)*255/screen->rfbServerFormat.greenMax,f);
	       fputc(((r>>screen->rfbServerFormat.blueShift)&screen->rfbServerFormat.blueMax)*255/screen->rfbServerFormat.blueMax,f);
	    }
	  fclose(f);
       }
#endif
  }
#ifndef NO_SHM
  XShmDetach(dpy,framebufferImage);
#endif

  return(0);
}