summaryrefslogtreecommitdiffstats
path: root/vncviewer/Viewport.h
blob: c66c19a0f4567c0ae64b529a50cbd891f43689d4 (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
169
/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
 * Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
 * 
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 * USA.
 */

#ifndef __VIEWPORT_H__
#define __VIEWPORT_H__

#include <map>

#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/Fl_RGB_Image.H>

#include <rfb/Rect.h>
#include <rfb/Region.h>
#include <rfb/Timer.h>
#include <rfb/PixelBuffer.h>
#include <rfb/PixelTransformer.h>

#if defined(WIN32)
#include "Win32PixelBuffer.h"
#elif defined(__APPLE__)
#include "OSXPixelBuffer.h"
#else
#include "X11PixelBuffer.h"
#endif

// We also have a generic version of the above, using pure FLTK:
//
// #include "PlatformPixelBuffer.h"
//

class CConn;

class Viewport : public Fl_Widget {
public:

  Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_);
  ~Viewport();

  // PixelFormat of incoming write operations
  void setServerPF(const rfb::PixelFormat& pf);
  // Most efficient format (from Viewport's point of view)
  const rfb::PixelFormat &getPreferredPF();

  // Flush updates to screen
  void updateWindow();

  // Methods forwarded from CConn
  void setName(const char *name);

  void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);

  void fillRect(const rfb::Rect& r, rfb::Pixel pix) {
    if (pixelTrans) {
      rfb::Pixel pix2;
      if (colourMapChange)
        commitColourMap();
      pixelTrans->translatePixels(&pix, &pix2, 1);
      pix = pix2;
    }

    frameBuffer->fillRect(r, pix);
    damageRect(r);
  }
  void imageRect(const rfb::Rect& r, void* pixels) {
    if (pixelTrans) {
      if (colourMapChange)
        commitColourMap();
      pixelTrans->translateRect(pixels, r.width(),
                                rfb::Rect(0, 0, r.width(), r.height()),
                                frameBuffer->data, frameBuffer->getStride(),
                                r.tl);
    } else {
      frameBuffer->imageRect(r, pixels);
    }
    damageRect(r);
  }
  void copyRect(const rfb::Rect& r, int srcX, int srcY) {
    frameBuffer->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY));
    damageRect(r);
  }

  rdr::U8* getPixelsRW(const rfb::Rect& r, int* stride) {
    return frameBuffer->getPixelsRW(r, stride);
  }

  void damageRect(const rfb::Rect& r) {
    damage.assign_union(rfb::Region(r));
    if (!Fl::has_timeout(handleUpdateTimeout, this))
      Fl::add_timeout(0.500, handleUpdateTimeout, this);
  };

  void setCursor(int width, int height, const rfb::Point& hotspot,
                 void* data, void* mask);

  // Fl_Widget callback methods

  void draw();

  void resize(int x, int y, int w, int h);

  int handle(int event);

private:

  static void handleUpdateTimeout(void *data);

  void commitColourMap();

  static void handleClipboardChange(int source, void *data);

  void handlePointerEvent(const rfb::Point& pos, int buttonMask);
  static void handlePointerTimeout(void *data);

  rdr::U32 translateKeyEvent(int keyCode, int origKeyCode, const char *keyText);
  void handleKeyEvent(int keyCode, int origKeyCode, const char *keyText, bool down);

  void initContextMenu();
  void popupContextMenu();

  void setMenuKey();

  static void handleOptions(void *data);

private:
  CConn* cc;

  PlatformPixelBuffer* frameBuffer;

  rfb::PixelTransformer *pixelTrans;
  rfb::SimpleColourMap colourMap;
  bool colourMapChange;

  rfb::Region damage;

  rfb::Point lastPointerPos;
  int lastButtonMask;

  typedef std::map<int, rdr::U32> DownMap;
  DownMap downKeySym;

  int menuKeyCode;
  Fl_Menu_Button *contextMenu;

  bool menuCtrlKey;
  bool menuAltKey;

  Fl_RGB_Image *cursor;
  rfb::Point cursorHotspot;
};

#endif