summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/arch.h9
-rw-r--r--libxrdp/xrdp_mppc_enc.c29
-rw-r--r--libxrdp/xrdp_rdp.c43
-rw-r--r--sesman/chansrv/chansrv.c7
-rw-r--r--vrplayer/decoder.cpp1
-rw-r--r--vrplayer/decoderthread.cpp22
-rw-r--r--vrplayer/demuxmedia.cpp116
-rw-r--r--vrplayer/demuxmedia.h32
-rw-r--r--vrplayer/dlgabout.ui2
-rw-r--r--vrplayer/main.cpp3
-rw-r--r--vrplayer/mainwindow.cpp100
-rw-r--r--vrplayer/mainwindow.h3
-rw-r--r--vrplayer/ourinterface.cpp31
-rw-r--r--vrplayer/ourinterface.h7
-rw-r--r--vrplayer/playaudio.cpp4
-rw-r--r--vrplayer/playvideo.cpp176
-rw-r--r--vrplayer/playvideo.h32
-rw-r--r--xorg/server/module/rdp.h106
-rw-r--r--xorg/server/module/rdpClientCon.c1100
-rw-r--r--xorg/server/module/rdpClientCon.h39
-rw-r--r--xorg/server/module/rdpDraw.c89
-rw-r--r--xorg/server/module/rdpDraw.h6
-rw-r--r--xorg/server/module/rdpGlyphs.c26
-rw-r--r--xorg/server/module/rdpGlyphs.h29
-rw-r--r--xorg/server/module/rdpMisc.c28
-rw-r--r--xorg/server/module/rdpMisc.h260
-rw-r--r--xorg/server/module/rdpPolyFillRect.c33
-rw-r--r--xrdpvr/xrdpvr.c265
-rw-r--r--xrdpvr/xrdpvr.h6
-rw-r--r--xrdpvr/xrdpvr_internal.h4
30 files changed, 2140 insertions, 468 deletions
diff --git a/common/arch.h b/common/arch.h
index 6a29b0a9..988153c2 100644
--- a/common/arch.h
+++ b/common/arch.h
@@ -32,6 +32,12 @@
defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \
defined(__ia64__) || defined(__ppc__) || defined(__arm__)
#define NEED_ALIGN
+#elif defined(__x86__) || defined(__x86_64__) || \
+ defined(__AMD64__) || defined(_M_IX86) || \
+ defined(__i386__)
+#define NO_NEED_ALIGN
+#else
+#warning unknown arch
#endif
#endif
@@ -62,6 +68,8 @@
#define EXPORT_CC
#endif
+#ifndef DEFINED_Ts
+#define DEFINED_Ts
typedef char ti8;
typedef unsigned char tui8;
typedef signed char tsi8;
@@ -94,5 +102,6 @@ typedef int tsock;
typedef unsigned long long tui64;
typedef signed long long tsi64;
#endif
+#endif
#endif
diff --git a/libxrdp/xrdp_mppc_enc.c b/libxrdp/xrdp_mppc_enc.c
index 05aa6bb6..15125d54 100644
--- a/libxrdp/xrdp_mppc_enc.c
+++ b/libxrdp/xrdp_mppc_enc.c
@@ -573,18 +573,21 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
outputBuffer = enc->outputBuffer;
g_memset(outputBuffer, 0, len);
enc->flags = PACKET_COMPR_TYPE_64K;
+
if (enc->first_pkt)
{
enc->first_pkt = 0;
enc->flagsHold |= PACKET_AT_FRONT;
}
- if ((enc->historyOffset + len) > enc->buf_len)
+ if ((enc->historyOffset + len) >= enc->buf_len)
{
/* historyBuffer cannot hold srcData - rewind it */
enc->historyOffset = 0;
- enc->flagsHold |= PACKET_AT_FRONT;
g_memset(hash_table, 0, enc->buf_len * 2);
+ g_memset(enc->historyBuffer, 0, enc->buf_len); // added
+ enc->first_pkt = 0;
+ enc->flagsHold |= PACKET_AT_FRONT;
}
/* point to next free byte in historyBuffer */
@@ -602,7 +605,7 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
/* first 2 bytes,because minimum LoM is 3 */
if (historyOffset == 0)
{
- /* encode first two bytes are literals */
+ /* encode first two bytes as literals */
for (x = 0; x < 2; x++)
{
data = *(historyPointer + x);
@@ -974,8 +977,14 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
/* give up */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
+ g_memset(enc->historyBuffer, 0, enc->buf_len);
enc->flagsHold |= PACKET_FLUSHED;
enc->first_pkt = 1;
+
+ g_memcpy(enc->outputBuffer, srcData, len);
+ enc->bytes_in_opb = len;
+ enc->flags = 0x81;
+
return 1;
}
else if (opb_index + 1 > len)
@@ -984,8 +993,14 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
/* give up */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
+ g_memset(enc->historyBuffer, 0, enc->buf_len);
enc->flagsHold |= PACKET_FLUSHED;
enc->first_pkt = 1;
+
+ g_memcpy(enc->outputBuffer, srcData, len);
+ enc->bytes_in_opb = len;
+ enc->flags = 0x81;
+
return 1;
}
@@ -1000,8 +1015,14 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
/* give up */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
+ g_memset(enc->historyBuffer, 0, enc->buf_len);
enc->flagsHold |= PACKET_FLUSHED;
enc->first_pkt = 1;
+
+ g_memcpy(enc->outputBuffer, srcData, len);
+ enc->bytes_in_opb = len;
+ enc->flags = 0x81;
+
return 1;
}
enc->flags |= PACKET_COMPRESSED;
@@ -1011,6 +1032,8 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
enc->flagsHold = 0;
DLOG(("\n"));
+ //g_writeln("compression ratio: %f", (float) len / (float) enc->bytes_in_opb);
+
return 1;
}
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 48deb6e2..7e68ec1f 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -400,29 +400,26 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
"tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb,
mppc_enc->historyOffset, tocomplen));
- if (mppc_enc->flags & RDP_MPPC_COMPRESSED)
- {
- clen = mppc_enc->bytes_in_opb + 18;
- pdulen = clen;
- ctype = mppc_enc->flags;
- iso_offset = (int)(s->iso_hdr - s->data);
- mcs_offset = (int)(s->mcs_hdr - s->data);
- sec_offset = (int)(s->sec_hdr - s->data);
- rdp_offset = (int)(s->rdp_hdr - s->data);
-
- /* outputBuffer has 64 bytes preceding it */
- ls.data = mppc_enc->outputBuffer - (rdp_offset + 18);
- ls.p = ls.data + rdp_offset;
- ls.end = ls.p + clen;
- ls.size = clen;
- ls.iso_hdr = ls.data + iso_offset;
- ls.mcs_hdr = ls.data + mcs_offset;
- ls.sec_hdr = ls.data + sec_offset;
- ls.rdp_hdr = ls.data + rdp_offset;
- ls.channel_hdr = 0;
- ls.next_packet = 0;
- s = &ls;
- }
+ clen = mppc_enc->bytes_in_opb + 18;
+ pdulen = clen;
+ ctype = mppc_enc->flags;
+ iso_offset = (int)(s->iso_hdr - s->data);
+ mcs_offset = (int)(s->mcs_hdr - s->data);
+ sec_offset = (int)(s->sec_hdr - s->data);
+ rdp_offset = (int)(s->rdp_hdr - s->data);
+
+ /* outputBuffer has 64 bytes preceding it */
+ ls.data = mppc_enc->outputBuffer - (rdp_offset + 18);
+ ls.p = ls.data + rdp_offset;
+ ls.end = ls.p + clen;
+ ls.size = clen;
+ ls.iso_hdr = ls.data + iso_offset;
+ ls.mcs_hdr = ls.data + mcs_offset;
+ ls.sec_hdr = ls.data + sec_offset;
+ ls.rdp_hdr = ls.data + rdp_offset;
+ ls.channel_hdr = 0;
+ ls.next_packet = 0;
+ s = &ls;
}
else
{
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index 01c6a43d..964c7abc 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -647,8 +647,9 @@ process_message_channel_data(struct stream *s)
{
rv = drdynvc_data_in(s, chan_id, chan_flags, length, total_length);
}
- else if (chan_id == ((struct xrdp_api_data *)
- (g_api_con_trans->callback_data))->chan_id)
+ else if ((g_api_con_trans != 0) &&
+ (chan_id == ((struct xrdp_api_data *)
+ (g_api_con_trans->callback_data))->chan_id))
{
LOG(10, ("process_message_channel_data length %d total_length %d "
"chan_flags 0x%8.8x", length, total_length, chan_flags));
@@ -664,7 +665,7 @@ process_message_channel_data(struct stream *s)
if (chan_flags & 2) /* last */
{
s_mark_end(ls);
- trans_write_copy(g_api_con_trans);
+ rv = trans_force_write(g_api_con_trans);
}
}
}
diff --git a/vrplayer/decoder.cpp b/vrplayer/decoder.cpp
index b1741997..10e562e9 100644
--- a/vrplayer/decoder.cpp
+++ b/vrplayer/decoder.cpp
@@ -13,6 +13,7 @@ Decoder::Decoder(QObject *parent) :
*****************************************************************************/
int Decoder::init(QString filename)
{
+ printf("Decoder::init\n");
if (channel)
return -1;
diff --git a/vrplayer/decoderthread.cpp b/vrplayer/decoderthread.cpp
index e31b1aa3..36ba4c85 100644
--- a/vrplayer/decoderthread.cpp
+++ b/vrplayer/decoderthread.cpp
@@ -1,3 +1,23 @@
+
+
+// not used
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#include "decoderthread.h"
/*
@@ -178,7 +198,7 @@ void DecoderThread::videoTimerCallback()
}
pkt = videoQueue.dequeue();
- delayInMs = (int) ((float) pkt->delay_in_us / 1000.0);
+ delayInMs = (int) 10; // ((float) pkt->delay_in_us / 1000.0);
send_video_pkt(channel, 101, pkt->av_pkt);
delete pkt;
updateSlider();
diff --git a/vrplayer/demuxmedia.cpp b/vrplayer/demuxmedia.cpp
index c6893ceb..0e2091f6 100644
--- a/vrplayer/demuxmedia.cpp
+++ b/vrplayer/demuxmedia.cpp
@@ -3,26 +3,25 @@
#include "demuxmedia.h"
-DemuxMedia::DemuxMedia(QObject *parent, QQueue<MediaPacket *> *audioQueue,
- QQueue<MediaPacket *> *videoQueue, void *channel, int stream_id) :
- QObject(parent)
+DemuxMedia::DemuxMedia(QObject *parent, QQueue<MediaPacket *> *videoQueue,
+ void *channel, int stream_id) : QObject(parent)
{
- this->audioQueue = audioQueue;
- this->videoQueue = videoQueue;
this->channel = channel;
this->stream_id = stream_id;
- this->threadsStarted = false;
this->vcrFlag = 0;
+ this->elapsedTime = 0;
+ this->la_seekPos = -1;
+ this->isStopped = 0;
+ this->pausedTime = 0;
+ this->videoQueue = videoQueue;
- playAudio = new PlayAudio(NULL, audioQueue, &sendMutex, channel, 101);
- playAudioThread = new QThread(this);
- connect(playAudioThread, SIGNAL(started()), playAudio, SLOT(play()));
- playAudio->moveToThread(playAudioThread);
-
- playVideo = new PlayVideo(NULL, videoQueue, &sendMutex, channel, 101);
+ playVideo = new PlayVideo(NULL, videoQueue, &sendMutex, channel, 101, 24);
playVideoThread = new QThread(this);
connect(playVideoThread, SIGNAL(started()), playVideo, SLOT(play()));
playVideo->moveToThread(playVideoThread);
+
+ playVideoThread->start();
+
}
void DemuxMedia::setVcrOp(int op)
@@ -30,12 +29,6 @@ void DemuxMedia::setVcrOp(int op)
vcrMutex.lock();
vcrFlag = op;
vcrMutex.unlock();
-
- if (playVideo)
- playVideo->setVcrOp(op);
-
- if (playAudio)
- playAudio->setVcrOp(op);
}
void DemuxMedia::startDemuxing()
@@ -44,9 +37,6 @@ void DemuxMedia::startDemuxing()
int is_video_frame;
int rv;
- if ((audioQueue == NULL) || (videoQueue == NULL))
- return;
-
while (1)
{
vcrMutex.lock();
@@ -55,18 +45,40 @@ void DemuxMedia::startDemuxing()
case VCR_PLAY:
vcrFlag = 0;
vcrMutex.unlock();
+ if (pausedTime)
+ {
+ elapsedTime = av_gettime() - pausedTime;
+ pausedTime = 0;
+ }
+ isStopped = false;
continue;
break;
case VCR_PAUSE:
vcrMutex.unlock();
+ if (!pausedTime)
+ {
+ /* save amount of video played so far */
+ pausedTime = av_gettime() - elapsedTime;
+ }
usleep(1000 * 100);
+ isStopped = false;
continue;
break;
case VCR_STOP:
vcrMutex.unlock();
- usleep(1000 * 100);
+
+ if (isStopped)
+ {
+ usleep(1000 * 100);
+ continue;
+ }
+ elapsedTime = 0;
+ pausedTime = 0;
+ la_seekPos = -1;
+ xrdpvr_seek_media(0, 0);
+ isStopped = true;
continue;
break;
@@ -75,14 +87,6 @@ void DemuxMedia::startDemuxing()
break;
}
- if ((audioQueue->count() >= 20) || (videoQueue->count() >= 20))
- {
- if (!threadsStarted)
- startAudioVideoThreads();
-
- usleep(1000 * 20);
- }
-
mediaPkt = new MediaPacket;
rv = xrdpvr_get_frame(&mediaPkt->av_pkt,
&is_video_frame,
@@ -91,31 +95,61 @@ void DemuxMedia::startDemuxing()
{
/* looks like we reached end of file */
delete mediaPkt;
- playVideo->onMediaRestarted();
usleep(1000 * 100);
xrdpvr_seek_media(0, 0);
+ this->elapsedTime = 0;
continue;
}
if (is_video_frame)
+ {
+ sendMutex.lock();
+#if 1
videoQueue->enqueue(mediaPkt);
+#else
+ send_video_pkt(channel, stream_id, mediaPkt->av_pkt);
+ delete mediaPkt;
+#endif
+ sendMutex.unlock();
+ }
else
- audioQueue->enqueue(mediaPkt);
+ {
+ int frame;
+ sendMutex.lock();
+ send_audio_pkt(channel, stream_id, mediaPkt->av_pkt);
+ sendMutex.unlock();
+ xrdpvr_read_ack(channel, &frame);
+ delete mediaPkt;
+ }
+
+ updateMediaPos();
+ if (elapsedTime == 0)
+ {
+ elapsedTime = av_gettime();
+ }
+
+ /* time elapsed in 1/100th sec units since play started */
+ emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
+
} /* end while (1) */
}
-PlayVideo * DemuxMedia::getPlayVideoInstance()
+void DemuxMedia::onMediaSeek(int value)
{
- return this->playVideo;
+ posMutex.lock();
+ la_seekPos = value;
+ posMutex.unlock();
}
-void DemuxMedia::startAudioVideoThreads()
+void DemuxMedia::updateMediaPos()
{
- if (threadsStarted)
- return;
-
- playVideoThread->start();
- playAudioThread->start();
- threadsStarted = true;
+ posMutex.lock();
+ if (la_seekPos >= 0)
+ {
+ xrdpvr_seek_media(la_seekPos, 0);
+ elapsedTime = av_gettime() - la_seekPos * 1000000;
+ la_seekPos = -1;
+ }
+ posMutex.unlock();
}
diff --git a/vrplayer/demuxmedia.h b/vrplayer/demuxmedia.h
index b83a8857..0b3935d7 100644
--- a/vrplayer/demuxmedia.h
+++ b/vrplayer/demuxmedia.h
@@ -37,33 +37,39 @@ class DemuxMedia : public QObject
Q_OBJECT
public:
- explicit DemuxMedia(QObject *parent = 0, QQueue<MediaPacket *> *audioQueue = 0,
- QQueue<MediaPacket *> *videoQueue = 0, void *channel = 0, int stream_id = 101);
+ explicit DemuxMedia(QObject *parent = 0, QQueue<MediaPacket *> *videoQueue = 0,
+ void *channel = 0, int stream_id = 101);
void setVcrOp(int op);
public slots:
void startDemuxing();
- PlayVideo *getPlayVideoInstance();
+ void onMediaSeek(int value);
private:
- QQueue<MediaPacket *> *audioQueue;
+ QMutex vcrMutex;
+ int vcrFlag;
+ void *channel;
+ int stream_id;
+ QMutex sendMutex;
+ QMutex posMutex;
+ int64_t elapsedTime; /* elapsed time in usecs since play started */
+ int64_t pausedTime; /* time at which stream was paused */
+ int64_t la_seekPos; /* locked access; must hold posMutex */
+ bool isStopped;
+
QQueue<MediaPacket *> *videoQueue;
- QMutex vcrMutex;
- int vcrFlag;
- void *channel;
PlayVideo *playVideo;
QThread *playVideoThread;
- PlayAudio *playAudio;
- QThread *playAudioThread;
- int stream_id;
- bool threadsStarted;
- QMutex sendMutex;
- void startAudioVideoThreads();
+ void updateMediaPos();
signals:
void onMediaRestarted();
+
+signals:
+ void onElapsedtime(int val); /* in hundredth of a sec */
+
};
#endif // DEMUXMEDIA_H
diff --git a/vrplayer/dlgabout.ui b/vrplayer/dlgabout.ui
index 8b2c38e5..beb5d837 100644
--- a/vrplayer/dlgabout.ui
+++ b/vrplayer/dlgabout.ui
@@ -23,7 +23,7 @@
</rect>
</property>
<property name="text">
- <string>VRPlayer v1.2</string>
+ <string>VRPlayer v1.4</string>
</property>
</widget>
<widget class="QPushButton" name="okButton">
diff --git a/vrplayer/main.cpp b/vrplayer/main.cpp
index d951345f..5e4821ab 100644
--- a/vrplayer/main.cpp
+++ b/vrplayer/main.cpp
@@ -1,11 +1,12 @@
+
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
+ QApplication::setGraphicsSystem(QLatin1String("native"));
QApplication a(argc, argv);
MainWindow w;
w.show();
-
return a.exec();
}
diff --git a/vrplayer/mainwindow.cpp b/vrplayer/mainwindow.cpp
index 1782f710..0ce04674 100644
--- a/vrplayer/mainwindow.cpp
+++ b/vrplayer/mainwindow.cpp
@@ -66,8 +66,8 @@ MainWindow::~MainWindow()
{
delete ui;
- if (moveResizeTimer)
- delete moveResizeTimer;
+ //if (moveResizeTimer)
+ // delete moveResizeTimer;
}
void MainWindow::closeEvent(QCloseEvent *event)
@@ -86,56 +86,56 @@ void MainWindow::closeEvent(QCloseEvent *event)
void MainWindow::resizeEvent(QResizeEvent *)
{
- if (vcrFlag != VCR_PLAY)
+ //if (vcrFlag != VCR_PLAY)
{
QRect rect;
getVdoGeometry(&rect);
interface->sendGeometry(rect);
- return;
+ //return;
}
- interface->setVcrOp(VCR_PAUSE);
- vcrFlag = VCR_PAUSE;
-
- if (!moveResizeTimer)
- {
- moveResizeTimer = new QTimer;
- connect(moveResizeTimer, SIGNAL(timeout()),
- this, SLOT(onMoveCompleted()));
- }
- lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
- moveResizeTimer->start(1000);
+ //interface->setVcrOp(VCR_PAUSE);
+ //vcrFlag = VCR_PAUSE;
+
+ //if (!moveResizeTimer)
+ //{
+ // moveResizeTimer = new QTimer;
+ // connect(moveResizeTimer, SIGNAL(timeout()),
+ // this, SLOT(onMoveCompleted()));
+ //}
+ //lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
+ //moveResizeTimer->start(1000);
}
void MainWindow::moveEvent(QMoveEvent *)
{
- if (vcrFlag != VCR_PLAY)
+ //if (vcrFlag != VCR_PLAY)
{
QRect rect;
getVdoGeometry(&rect);
interface->sendGeometry(rect);
- return;
+ //return;
}
- interface->setVcrOp(VCR_PAUSE);
- vcrFlag = VCR_PAUSE;
-
- if (!moveResizeTimer)
- {
- moveResizeTimer = new QTimer;
- connect(moveResizeTimer, SIGNAL(timeout()),
- this, SLOT(onMoveCompleted()));
- }
- lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
- moveResizeTimer->start(1000);
+ //interface->setVcrOp(VCR_PAUSE);
+ //vcrFlag = VCR_PAUSE;
+
+ //if (!moveResizeTimer)
+ //{
+ // moveResizeTimer = new QTimer;
+ // connect(moveResizeTimer, SIGNAL(timeout()),
+ // this, SLOT(onMoveCompleted()));
+ //}
+ //lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
+ //moveResizeTimer->start(1000);
}
void MainWindow::onVolSliderValueChanged(int value)
{
int volume;
-
+
volume = (value * 0xffff) / 100;
if (interface != 0)
{
@@ -153,8 +153,8 @@ void MainWindow::setupUI()
lblVideo->setMinimumWidth(320);
lblVideo->setMinimumHeight(200);
QPalette palette = lblVideo->palette();
- palette.setColor(lblVideo->backgroundRole(), Qt::black);
- palette.setColor(lblVideo->foregroundRole(), Qt::black);
+ palette.setColor(lblVideo->backgroundRole(), QColor(0x00, 0x00, 0x01, 0xff));
+ palette.setColor(lblVideo->foregroundRole(), QColor(0x00, 0x00, 0x01, 0xff));
lblVideo->setAutoFillBackground(true);
lblVideo->setPalette(palette);
hboxLayoutTop = new QHBoxLayout;
@@ -253,10 +253,17 @@ void MainWindow::openMediaFile()
if (filename.length() == 0)
{
+
/* no previous selection - open user's home folder TODO */
// TODO filename = QFileDialog::getOpenFileName(this, "Select Media File", "/");
+ //filename = QFileDialog::getOpenFileName(this, "Select Media File",
+ // QDir::currentPath());
+
filename = QFileDialog::getOpenFileName(this, "Select Media File",
- QDir::currentPath());
+ QDir::currentPath(),
+ "Media *.mov *.mp4 *.mkv (*.mov *.mp4 *.mkv)");
+
+
}
else
{
@@ -302,13 +309,19 @@ void MainWindow::clearDisplay()
void MainWindow::on_actionOpen_Media_File_triggered()
{
if (vcrFlag != 0)
+ {
onBtnStopClicked(true);
+ }
/* if media was specified on cmd line, use it just once */
if (gotMediaOnCmdline)
+ {
gotMediaOnCmdline = false;
+ }
else
+ {
openMediaFile();
+ }
if (filename.length() == 0)
{
@@ -327,10 +340,10 @@ void MainWindow::on_actionOpen_Media_File_triggered()
interface->initRemoteClient();
}
- playVideo = interface->getPlayVideoInstance();
- if (playVideo)
+ demuxMedia = interface->getDemuxMediaInstance();
+ if (demuxMedia)
{
- connect(playVideo, SIGNAL(onElapsedtime(int)),
+ connect(demuxMedia, SIGNAL(onElapsedtime(int)),
this, SLOT(onElapsedTime(int)));
}
@@ -355,7 +368,7 @@ void MainWindow::onBtnPlayClicked(bool)
{
if (vcrFlag == 0)
{
- /* first time play button has been clicked */
+ /* first time play button3 has been clicked */
on_actionOpen_Media_File_triggered();
btnPlay->setText("Pause");
vcrFlag = VCR_PLAY;
@@ -385,8 +398,8 @@ void MainWindow::onBtnPlayClicked(bool)
void MainWindow::onBtnRewindClicked(bool)
{
- if (playVideo)
- playVideo->onMediaSeek(0);
+ //if (playVideo)
+ // playVideo->onMediaSeek(0);
}
void MainWindow::onBtnStopClicked(bool)
@@ -401,6 +414,8 @@ void MainWindow::onBtnStopClicked(bool)
/* clear screen by filling it with black */
clearDisplay();
+
+ btnPlay->setChecked(false);
}
void MainWindow::onMediaDurationInSeconds(int duration)
@@ -479,8 +494,10 @@ void MainWindow::onSliderValueChanged(int value)
if (acceptSliderMove)
{
acceptSliderMove = false;
- if (playVideo)
- playVideo->onMediaSeek(value / 100);
+ if (demuxMedia != NULL)
+ {
+ demuxMedia->onMediaSeek(value / 100);
+ }
}
}
@@ -503,6 +520,7 @@ void MainWindow::onSliderActionTriggered(int action)
}
}
+// not called
void MainWindow::onMoveCompleted()
{
QRect rect;
@@ -512,7 +530,7 @@ void MainWindow::onMoveCompleted()
interface->setVcrOp(VCR_PLAY);
vcrFlag = VCR_PLAY;
- moveResizeTimer->stop();
+ //moveResizeTimer->stop();
}
void MainWindow::on_actionAbout_triggered()
diff --git a/vrplayer/mainwindow.h b/vrplayer/mainwindow.h
index 4fef0d60..f0383098 100644
--- a/vrplayer/mainwindow.h
+++ b/vrplayer/mainwindow.h
@@ -111,7 +111,8 @@ private:
/* private stuff */
OurInterface *interface;
- PlayVideo *playVideo;
+ //PlayVideo *playVideo;
+ DemuxMedia *demuxMedia;
QString filename;
bool oneTimeInitSuccess;
bool remoteClientInited;
diff --git a/vrplayer/ourinterface.cpp b/vrplayer/ourinterface.cpp
index cee66691..e13e6e8b 100644
--- a/vrplayer/ourinterface.cpp
+++ b/vrplayer/ourinterface.cpp
@@ -1,3 +1,4 @@
+
#include "ourinterface.h"
OurInterface::OurInterface(QObject *parent) :
@@ -59,11 +60,11 @@ void OurInterface::initRemoteClient()
/* LK_TODO this needs to be undone in deinitRemoteClient() */
if (!demuxMedia)
{
- demuxMedia = new DemuxMedia(NULL, &audioQueue, &videoQueue, channel, stream_id);
+ demuxMedia = new DemuxMedia(NULL, &videoQueue, channel, stream_id);
demuxMediaThread = new QThread(this);
connect(demuxMediaThread, SIGNAL(started()), demuxMedia, SLOT(startDemuxing()));
demuxMedia->moveToThread(demuxMediaThread);
- playVideo = demuxMedia->getPlayVideoInstance();
+ //playVideo = demuxMedia->getPlayVideoInstance();
}
}
@@ -84,6 +85,7 @@ int OurInterface::openVirtualChannel()
if (channel)
return -1;
+ printf("OurInterface::openVirtualChannel:\n");
/* open a virtual channel and connect to remote client */
channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "xrdpvr", 0);
if (channel == NULL)
@@ -116,37 +118,46 @@ int OurInterface::closeVirtualChannel()
******************************************************************************/
int OurInterface::sendMetadataFile()
{
+
+ if (xrdpvr_init_player(channel, 101, filename.toAscii().data()))
+ {
+ fprintf(stderr, "failed to initialize the player\n");
+ return -1;
+ }
+#if 0
if (xrdpvr_create_metadata_file(channel, filename.toAscii().data()))
{
emit on_ErrorMsg("I/O Error",
"An error occurred while sending data to remote client");
return -1;
}
-
+#endif
return 0;
}
int OurInterface::sendVideoFormat()
{
+#if 0
if (xrdpvr_set_video_format(channel, stream_id))
{
emit on_ErrorMsg("I/O Error",
"Error sending video format to remote client");
return -1;
}
-
+#endif
return 0;
}
int OurInterface::sendAudioFormat()
{
+#if 0
if (xrdpvr_set_audio_format(channel, stream_id))
{
emit on_ErrorMsg("I/O Error",
"Error sending audio format to remote client");
return -1;
}
-
+#endif
return 0;
}
@@ -205,11 +216,17 @@ void OurInterface::playMedia()
demuxMediaThread->start();
}
-PlayVideo * OurInterface::getPlayVideoInstance()
+//PlayVideo * OurInterface::getPlayVideoInstance()
+//{
+// return this->playVideo;
+//}
+
+DemuxMedia * OurInterface::getDemuxMediaInstance()
{
- return this->playVideo;
+ return this->demuxMedia;
}
+
void OurInterface::setVcrOp(int op)
{
if (demuxMedia)
diff --git a/vrplayer/ourinterface.h b/vrplayer/ourinterface.h
index 86352001..51f88e6b 100644
--- a/vrplayer/ourinterface.h
+++ b/vrplayer/ourinterface.h
@@ -40,7 +40,8 @@ public:
int sendGeometry(QRect rect);
void setFilename(QString filename);
void playMedia();
- PlayVideo *getPlayVideoInstance();
+ //PlayVideo *getPlayVideoInstance();
+ DemuxMedia *getDemuxMediaInstance();
void setVcrOp(int op);
int setVolume(int volume);
@@ -54,12 +55,12 @@ signals:
private:
/* private stuff */
- QQueue<MediaPacket *> audioQueue;
+
QQueue<MediaPacket *> videoQueue;
DemuxMedia *demuxMedia;
QThread *demuxMediaThread;
- PlayVideo *playVideo;
+ //PlayVideo *playVideo;
QString filename;
void *channel;
int stream_id;
diff --git a/vrplayer/playaudio.cpp b/vrplayer/playaudio.cpp
index fee98f9d..042b7e26 100644
--- a/vrplayer/playaudio.cpp
+++ b/vrplayer/playaudio.cpp
@@ -54,13 +54,15 @@ void PlayAudio::play()
label1:
+ printf("audio\n");
if (audioQueue->isEmpty())
{
qDebug() << "PlayAudio::play: GOT EMPTY";
- usleep(1000 * 100);
+ usleep(1000 * 10);
continue;
}
+ printf("");
pkt = audioQueue->dequeue();
sendMutex->lock();
send_audio_pkt(channel, stream_id, pkt->av_pkt);
diff --git a/vrplayer/playvideo.cpp b/vrplayer/playvideo.cpp
index 24ef492d..71fbcda9 100644
--- a/vrplayer/playvideo.cpp
+++ b/vrplayer/playvideo.cpp
@@ -1,5 +1,6 @@
#include <unistd.h>
+#include <sys/time.h>
#include "playvideo.h"
#include <QDebug>
@@ -8,179 +9,58 @@ PlayVideo::PlayVideo(QObject *parent,
QQueue<MediaPacket *> *videoQueue,
QMutex *sendMutex,
void *channel,
- int stream_id) :
+ int stream_id, int fps) :
QObject(parent)
{
this->videoQueue = videoQueue;
this->channel = channel;
this->sendMutex = sendMutex;
this->stream_id = stream_id;
- elapsedTime = 0;
- pausedTime = 0;
- la_seekPos = -1;
- vcrFlag = 0;
- isStopped = false;
+ this->fps = fps;
+}
+
+/**
+ ******************************************************************************/
+static int
+get_mstime(void)
+{
+ struct timeval tp;
+
+ gettimeofday(&tp, 0);
+ return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
}
void PlayVideo::play()
{
MediaPacket *pkt;
- int usl;
+ int now_time;
+ int sleep_time;
+ int last_display_time;
+ last_display_time = 0;
while (1)
{
- vcrMutex.lock();
- switch (vcrFlag)
- {
- case VCR_PLAY:
- vcrFlag = 0;
- vcrMutex.unlock();
- if (pausedTime)
- {
- elapsedTime = av_gettime() - pausedTime;
- pausedTime = 0;
- }
- isStopped = false;
- continue;
- break;
-
- case VCR_PAUSE:
- vcrMutex.unlock();
- if (!pausedTime)
- {
- /* save amount of video played so far */
- pausedTime = av_gettime() - elapsedTime;
- }
- usleep(1000 * 100);
- isStopped = false;
- continue;
- break;
-
- case VCR_STOP:
- vcrMutex.unlock();
- if (isStopped)
- {
- usleep(1000 * 100);
- continue;
- }
- clearVideoQ();
- elapsedTime = 0;
- pausedTime = 0;
- la_seekPos = -1;
- xrdpvr_seek_media(0, 0);
- isStopped = true;
- continue;
- break;
-
- default:
- vcrMutex.unlock();
- goto label1;
- break;
- }
-
-label1:
-
+ sendMutex->lock();
if (videoQueue->isEmpty())
{
+ sendMutex->unlock();
+ usleep(10 * 1000);
continue;
}
pkt = videoQueue->dequeue();
- sendMutex->lock();
send_video_pkt(channel, stream_id, pkt->av_pkt);
sendMutex->unlock();
- usl = pkt->delay_in_us;
- if (usl < 0)
+ now_time = get_mstime();
+ sleep_time = now_time - last_display_time;
+ if (sleep_time > (1000 / fps))
{
- usl = 0;
+ sleep_time = (1000 / fps);
}
- if (usl > 100 * 1000)
+ if (sleep_time > 0)
{
- usl = 100 * 1000;
+ usleep(sleep_time * 1000);
}
- usleep(usl);
- delete pkt;
- updateMediaPos();
- if (elapsedTime == 0)
- elapsedTime = av_gettime();
-
- /* time elapsed in 1/100th sec units since play started */
- emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
- }
-}
-
-void PlayVideo::onMediaRestarted()
-{
- elapsedTime = av_gettime();
-}
-
-void PlayVideo::onMediaSeek(int value)
-{
- posMutex.lock();
- la_seekPos = value;
- posMutex.unlock();
-}
-
-void PlayVideo::updateMediaPos()
-{
-#if 0
- if (elapsedTime == 0)
- elapsedTime = av_gettime();
-
- /* time elapsed in 1/100th sec units since play started */
- emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
-#endif
-
- posMutex.lock();
- if (la_seekPos >= 0)
- {
- //qDebug() << "seeking to" << la_seekPos;
- xrdpvr_seek_media(la_seekPos, 0);
- elapsedTime = av_gettime() - la_seekPos * 1000000;
- la_seekPos = -1;
- }
- posMutex.unlock();
-}
-
-void PlayVideo::setVcrOp(int op)
-{
- vcrMutex.lock();
- this->vcrFlag = op;
- vcrMutex.unlock();
-}
-
-void PlayVideo::clearVideoQ()
-{
- MediaPacket *pkt;
-
- while (!videoQueue->isEmpty())
- {
- pkt = videoQueue->dequeue();
- av_free_packet((AVPacket *) pkt->av_pkt);
+ last_display_time = now_time;
delete pkt;
}
}
-
-#if 0
-void DecoderThread::updateSlider()
-{
- if (elapsedTime == 0)
- elapsedTime = av_gettime();
-
- /* time elapsed in 1/100th sec units since play started */
- emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
-
- mutex.lock();
- if (la_seekPos >= 0)
- {
- //qDebug() << "seeking to" << la_seekPos;
- //audioTimer->stop();
- //videoTimer->stop();
- xrdpvr_seek_media(la_seekPos, 0);
- elapsedTime = av_gettime() - la_seekPos * 1000000;
- //audioTimer->start(10);
- //videoTimer->start(10);
- la_seekPos = -1;
- }
- mutex.unlock();
-}
-#endif
diff --git a/vrplayer/playvideo.h b/vrplayer/playvideo.h
index 2ae183b5..e2300f24 100644
--- a/vrplayer/playvideo.h
+++ b/vrplayer/playvideo.h
@@ -39,34 +39,36 @@ public:
QQueue<MediaPacket *> *videoQueue = 0,
QMutex *sendMutex = 0,
void *channel = 0,
- int stream_id = 101);
+ int stream_id = 101,
+ int fps = 24);
- void onMediaSeek(int value);
- void setVcrOp(int op);
- void onMediaRestarted();
+ //void onMediaSeek(int value);
+ //void setVcrOp(int op);
+ //void onMediaRestarted();
public slots:
void play();
-signals:
- void onElapsedtime(int val); /* in hundredth of a sec */
+//signals:
+// void onElapsedtime(int val); /* in hundredth of a sec */
private:
QQueue<MediaPacket *> *videoQueue;
- int vcrFlag;
- QMutex vcrMutex;
+// int vcrFlag;
+// QMutex vcrMutex;
QMutex *sendMutex;
- QMutex posMutex;
- int64_t la_seekPos; /* locked access; must hold posMutex */
+// QMutex posMutex;
+// int64_t la_seekPos; /* locked access; must hold posMutex */
void *channel;
int stream_id;
- int64_t elapsedTime; /* elapsed time in usecs since play started */
- int64_t pausedTime; /* time at which stream was paused */
- bool isStopped;
+ int fps;
+// int64_t elapsedTime; /* elapsed time in usecs since play started */
+// int64_t pausedTime; /* time at which stream was paused */
+// bool isStopped;
- void updateMediaPos();
- void clearVideoQ();
+// void updateMediaPos();
+// void clearVideoQ();
};
#endif // PLAYVIDEO_H
diff --git a/xorg/server/module/rdp.h b/xorg/server/module/rdp.h
index c3533e98..4c6511e0 100644
--- a/xorg/server/module/rdp.h
+++ b/xorg/server/module/rdp.h
@@ -65,6 +65,26 @@ struct _rdpKeyboard
};
typedef struct _rdpKeyboard rdpKeyboard;
+
+struct _rdpPixmapRec
+{
+ int status;
+ int rdpindex;
+ int con_number;
+ int is_dirty;
+ int is_scratch;
+ int is_alpha_dirty_not;
+ /* number of times used in a remote operation
+ if this gets above XRDP_USE_COUNT_THRESHOLD
+ then we force remote the pixmap */
+ int use_count;
+ int kind_width;
+ struct rdp_draw_item *draw_item_head;
+ struct rdp_draw_item *draw_item_tail;
+};
+typedef struct _rdpPixmapRec rdpPixmapRec;
+typedef struct _rdpPixmapRec * rdpPixmapPtr;
+
/* move this to common header */
struct _rdpRec
{
@@ -75,6 +95,8 @@ struct _rdpRec
int sizeInBytes;
int num_modes;
int bitsPerPixel;
+ int Bpp;
+ int Bpp_mask;
char *pfbMemory;
ScreenPtr pScreen;
rdpDevPrivateKey privateKeyRecGC;
@@ -114,6 +136,20 @@ struct _rdpRec
char uds_data[256];
rdpClientCon *clientConHead;
rdpClientCon *clientConTail;
+
+ rdpPixmapRec screenPriv;
+ int sendUpdateScheduled; /* boolean */
+ OsTimerPtr sendUpdateTimer;
+
+ int do_dirty_ons; /* boolean */
+ int disconnect_scheduled; /* boolean */
+ int do_kill_disconnected; /* boolean */
+
+ OsTimerPtr disconnectTimer;
+ int disconnectScheduled; /* boolean */
+ int disconnect_timeout_s;
+ int disconnect_time_ms;
+
};
typedef struct _rdpRec rdpRec;
typedef struct _rdpRec * rdpPtr;
@@ -127,11 +163,73 @@ struct _rdpGCRec
typedef struct _rdpGCRec rdpGCRec;
typedef struct _rdpGCRec * rdpGCPtr;
-struct _rdpPixmapRec
+#define RDI_FILL 1
+#define RDI_IMGLL 2 /* lossless */
+#define RDI_IMGLY 3 /* lossy */
+#define RDI_LINE 4
+#define RDI_SCRBLT 5
+#define RDI_TEXT 6
+
+struct urdp_draw_item_fill
{
- int i1;
+ int opcode;
+ int fg_color;
+ int bg_color;
+ int pad0;
+};
+
+struct urdp_draw_item_img
+{
+ int opcode;
+ int pad0;
+};
+
+struct urdp_draw_item_line
+{
+ int opcode;
+ int fg_color;
+ int bg_color;
+ int width;
+ xSegment* segs;
+ int nseg;
+ int flags;
+};
+
+struct urdp_draw_item_scrblt
+{
+ int srcx;
+ int srcy;
+ int dstx;
+ int dsty;
+ int cx;
+ int cy;
+};
+
+struct urdp_draw_item_text
+{
+ int opcode;
+ int fg_color;
+ struct rdp_text* rtext; /* in rdpglyph.h */
+};
+
+union urdp_draw_item
+{
+ struct urdp_draw_item_fill fill;
+ struct urdp_draw_item_img img;
+ struct urdp_draw_item_line line;
+ struct urdp_draw_item_scrblt scrblt;
+ struct urdp_draw_item_text text;
+};
+
+struct rdp_draw_item
+{
+ int type; /* RDI_FILL, RDI_IMGLL, ... */
+ int flags;
+ struct rdp_draw_item* prev;
+ struct rdp_draw_item* next;
+ RegionPtr reg;
+ union urdp_draw_item u;
};
-typedef struct _rdpPixmapRec rdpPixmapRec;
-typedef struct _rdpPixmapRec * rdpPixmapPtr;
+#define XRDP_USE_COUNT_THRESHOLD 1
#endif
diff --git a/xorg/server/module/rdpClientCon.c b/xorg/server/module/rdpClientCon.c
index 3edd1e0c..b0ca3776 100644
--- a/xorg/server/module/rdpClientCon.c
+++ b/xorg/server/module/rdpClientCon.c
@@ -24,6 +24,8 @@ Client connection to xrdp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
/* this should be before all X11 .h files */
#include <xorg-server.h>
@@ -43,6 +45,53 @@ Client connection to xrdp
#define LTOUI32(_in) ((unsigned int)(_in))
+#define USE_MAX_OS_BYTES 1
+#define MAX_OS_BYTES (16 * 1024 * 1024)
+
+/*
+0 GXclear, 0
+1 GXnor, DPon
+2 GXandInverted, DPna
+3 GXcopyInverted, Pn
+4 GXandReverse, PDna
+5 GXinvert, Dn
+6 GXxor, DPx
+7 GXnand, DPan
+8 GXand, DPa
+9 GXequiv, DPxn
+a GXnoop, D
+b GXorInverted, DPno
+c GXcopy, P
+d GXorReverse, PDno
+e GXor, DPo
+f GXset 1
+*/
+
+static int g_rdp_opcodes[16] =
+{
+ 0x00, /* GXclear 0x0 0 */
+ 0x88, /* GXand 0x1 src AND dst */
+ 0x44, /* GXandReverse 0x2 src AND NOT dst */
+ 0xcc, /* GXcopy 0x3 src */
+ 0x22, /* GXandInverted 0x4 NOT src AND dst */
+ 0xaa, /* GXnoop 0x5 dst */
+ 0x66, /* GXxor 0x6 src XOR dst */
+ 0xee, /* GXor 0x7 src OR dst */
+ 0x11, /* GXnor 0x8 NOT src AND NOT dst */
+ 0x99, /* GXequiv 0x9 NOT src XOR dst */
+ 0x55, /* GXinvert 0xa NOT dst */
+ 0xdd, /* GXorReverse 0xb src OR NOT dst */
+ 0x33, /* GXcopyInverted 0xc NOT src */
+ 0xbb, /* GXorInverted 0xd NOT src OR dst */
+ 0x77, /* GXnand 0xe NOT src OR NOT dst */
+ 0xff /* GXset 0xf 1 */
+};
+
+static int
+rdpClientConSendPending(rdpPtr dev, rdpClientCon *clientCon);
+static int
+rdpClientConSendMsg(rdpPtr dev, rdpClientCon *clientCon);
+
/******************************************************************************/
static int
rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
@@ -219,13 +268,13 @@ rdpClientConInit(rdpPtr dev)
if (dev->listen_sck == 0)
{
unlink(dev->uds_data);
- dev->listen_sck = g_tcp_local_socket_stream();
- if (g_tcp_local_bind(dev->listen_sck, dev->uds_data) != 0)
+ dev->listen_sck = g_sck_local_socket_stream();
+ if (g_sck_local_bind(dev->listen_sck, dev->uds_data) != 0)
{
LLOGLN(0, ("rdpClientConInit: g_tcp_local_bind failed"));
return 1;
}
- g_tcp_listen(dev->listen_sck);
+ g_sck_listen(dev->listen_sck);
AddEnabledDevice(dev->listen_sck);
}
return 0;
@@ -243,3 +292,1048 @@ rdpClientConDeinit(rdpPtr dev)
}
return 0;
}
+
+/******************************************************************************/
+static CARD32
+rdpClientConDeferredDisconnectCallback(OsTimerPtr timer, CARD32 now,
+ pointer arg)
+{
+ CARD32 lnow_ms;
+ rdpPtr dev;
+
+ LLOGLN(10, ("rdpClientConDeferredDisconnectCallback"));
+ dev = (rdpPtr) arg;
+ if (dev->clientConHead != NULL) /* is there any connection ? */
+ {
+ LLOGLN(0, ("rdpClientConDeferredDisconnectCallback: one connected"));
+ if (dev->disconnectTimer != NULL)
+ {
+ LLOGLN(0, ("rdpClientConDeferredDisconnectCallback: "
+ "canceling disconnectTimer"));
+ TimerCancel(dev->disconnectTimer);
+ TimerFree(dev->disconnectTimer);
+ dev->disconnectTimer = NULL;
+ }
+ dev->disconnectScheduled = FALSE;
+ return 0;
+ }
+ else
+ {
+ LLOGLN(10, ("rdpClientConDeferredDisconnectCallback: not connected"));
+ }
+ lnow_ms = GetTimeInMillis();
+ if (lnow_ms - dev->disconnect_time_ms > dev->disconnect_timeout_s * 1000)
+ {
+ LLOGLN(0, ("rdpClientConDeferredDisconnectCallback: exit X11rdp"));
+ kill(getpid(), SIGTERM);
+ return 0;
+ }
+ dev->disconnectTimer = TimerSet(dev->disconnectTimer, 0, 1000 * 10,
+ rdpClientConDeferredDisconnectCallback,
+ dev);
+ return 0;
+}
+
+
+/*****************************************************************************/
+static int
+rdpClientConDisconnect(rdpPtr dev, rdpClientCon *clientCon)
+{
+ //int index;
+
+ LLOGLN(0, ("rdpClientConDisconnect:"));
+ if (dev->do_kill_disconnected)
+ {
+ if (dev->disconnect_scheduled == FALSE)
+ {
+ LLOGLN(0, ("rdpClientConDisconnect: starting g_dis_timer"));
+ dev->disconnectTimer = TimerSet(dev->disconnectTimer, 0, 1000 * 10,
+ rdpClientConDeferredDisconnectCallback, dev);
+ dev->disconnect_scheduled = TRUE;
+ }
+ dev->disconnect_time_ms = GetTimeInMillis();
+ }
+
+ //rdpClientConDelete(dev, clientCon);
+
+#if 0
+
+ // TODO
+
+ RemoveEnabledDevice(clientCon->sck);
+ clientCon->connected = FALSE;
+ g_sck_close(clientCon->sck);
+ clientCon->sck = 0;
+ clientCon->sckClosed = TRUE;
+ clientCon->osBitmapNumUsed = 0;
+ clientCon->rdpIndex = -1;
+
+ if (clientCon->maxOsBitmaps > 0)
+ {
+ for (index = 0; index < clientCon->maxOsBitmaps; index++)
+ {
+ if (clientCon->osBitmaps[index].used)
+ {
+ if (g_os_bitmaps[index].priv != 0)
+ {
+ g_os_bitmaps[index].priv->status = 0;
+ }
+ }
+ }
+ }
+ g_os_bitmap_alloc_size = 0;
+
+ g_max_os_bitmaps = 0;
+ g_free(g_os_bitmaps);
+ g_os_bitmaps = 0;
+ g_use_rail = 0;
+ g_do_glyph_cache = 0;
+ g_do_composite = 0;
+
+#endif
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConBeginUpdate(rdpPtr dev, rdpClientCon *clientCon)
+{
+ LLOGLN(10, ("rdpClientConBeginUpdate:"));
+
+ if (clientCon->connected)
+ {
+ if (clientCon->begin)
+ {
+ return 0;
+ }
+ init_stream(clientCon->out_s, 0);
+ s_push_layer(clientCon->out_s, iso_hdr, 8);
+ out_uint16_le(clientCon->out_s, 1); /* begin update */
+ out_uint16_le(clientCon->out_s, 4); /* size */
+ clientCon->begin = TRUE;
+ clientCon->count = 1;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConEndUpdate(rdpPtr dev, rdpClientCon *clientCon)
+{
+ LLOGLN(10, ("rdpClientConEndUpdate"));
+
+ if (clientCon->connected && clientCon->begin)
+ {
+ if (dev->do_dirty_ons)
+ {
+ /* in this mode, end update is only called in check dirty */
+ rdpClientConSendPending(dev, clientCon);
+ }
+ else
+ {
+ rdpClientConScheduleDeferredUpdate(dev);
+ }
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConPreCheck(rdpPtr dev, rdpClientCon *clientCon, int in_size)
+{
+ int rv;
+
+ rv = 0;
+ if (clientCon->begin == FALSE)
+ {
+ rdpClientConBeginUpdate(dev, clientCon);
+ }
+
+ if ((clientCon->out_s->p - clientCon->out_s->data) >
+ (clientCon->out_s->size - (in_size + 20)))
+ {
+ s_mark_end(clientCon->out_s);
+ if (rdpClientConSendMsg(dev, clientCon) != 0)
+ {
+ LLOGLN(0, ("rdpClientConPreCheck: rdpup_send_msg failed"));
+ rv = 1;
+ }
+ clientCon->count = 0;
+ init_stream(clientCon->out_s, 0);
+ s_push_layer(clientCon->out_s, iso_hdr, 8);
+ }
+
+ return rv;
+}
+
+/******************************************************************************/
+int
+rdpClientConFillRect(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, int cx, int cy)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConFillRect:"));
+ rdpClientConPreCheck(dev, clientCon, 12);
+ out_uint16_le(clientCon->out_s, 3); /* fill rect */
+ out_uint16_le(clientCon->out_s, 12); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint16_le(clientCon->out_s, cx);
+ out_uint16_le(clientCon->out_s, cy);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConScreenBlt(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, int cx, int cy, short srcx, short srcy)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConScreenBlt: x %d y %d cx %d cy %d "
+ "srcx %d srcy %d",
+ x, y, cx, cy, srcx, srcy));
+ rdpClientConPreCheck(dev, clientCon, 16);
+ out_uint16_le(clientCon->out_s, 4); /* screen blt */
+ out_uint16_le(clientCon->out_s, 16); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint16_le(clientCon->out_s, cx);
+ out_uint16_le(clientCon->out_s, cy);
+ out_uint16_le(clientCon->out_s, srcx);
+ out_uint16_le(clientCon->out_s, srcy);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetClip(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, int cx, int cy)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetClip:"));
+ rdpClientConPreCheck(dev, clientCon, 12);
+ out_uint16_le(clientCon->out_s, 10); /* set clip */
+ out_uint16_le(clientCon->out_s, 12); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint16_le(clientCon->out_s, cx);
+ out_uint16_le(clientCon->out_s, cy);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConResetClip(rdpPtr dev, rdpClientCon *clientCon)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConResetClip:"));
+ rdpClientConPreCheck(dev, clientCon, 4);
+ out_uint16_le(clientCon->out_s, 11); /* reset clip */
+ out_uint16_le(clientCon->out_s, 4); /* size */
+ clientCon->count++;
+ }
+
+ return 0;
+}
+
+#define COLOR8(r, g, b) \
+ ((((r) >> 5) << 0) | (((g) >> 5) << 3) | (((b) >> 6) << 6))
+#define COLOR15(r, g, b) \
+ ((((r) >> 3) << 10) | (((g) >> 3) << 5) | (((b) >> 3) << 0))
+#define COLOR16(r, g, b) \
+ ((((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0))
+#define COLOR24(r, g, b) \
+ ((((r) >> 0) << 0) | (((g) >> 0) << 8) | (((b) >> 0) << 16))
+#define SPLITCOLOR32(r, g, b, c) \
+ { \
+ r = ((c) >> 16) & 0xff; \
+ g = ((c) >> 8) & 0xff; \
+ b = (c) & 0xff; \
+ }
+
+/******************************************************************************/
+int
+rdpClientConConvertPixel(rdpPtr dev, rdpClientCon *clientCon, int in_pixel)
+{
+ int red;
+ int green;
+ int blue;
+ int rv;
+
+ rv = 0;
+
+ if (dev->depth == 24)
+ {
+ if (clientCon->rdp_bpp == 24)
+ {
+ rv = in_pixel;
+ SPLITCOLOR32(red, green, blue, rv);
+ rv = COLOR24(red, green, blue);
+ }
+ else if (clientCon->rdp_bpp == 16)
+ {
+ rv = in_pixel;
+ SPLITCOLOR32(red, green, blue, rv);
+ rv = COLOR16(red, green, blue);
+ }
+ else if (clientCon->rdp_bpp == 15)
+ {
+ rv = in_pixel;
+ SPLITCOLOR32(red, green, blue, rv);
+ rv = COLOR15(red, green, blue);
+ }
+ else if (clientCon->rdp_bpp == 8)
+ {
+ rv = in_pixel;
+ SPLITCOLOR32(red, green, blue, rv);
+ rv = COLOR8(red, green, blue);
+ }
+ }
+ else if (dev->depth == clientCon->rdp_bpp)
+ {
+ return in_pixel;
+ }
+
+ return rv;
+}
+
+/******************************************************************************/
+int
+rdpClientConConvertPixels(rdpPtr dev, rdpClientCon *clientCon,
+ void *src, void *dst, int num_pixels)
+{
+ unsigned int pixel;
+ unsigned int red;
+ unsigned int green;
+ unsigned int blue;
+ unsigned int *src32;
+ unsigned int *dst32;
+ unsigned short *dst16;
+ unsigned char *dst8;
+ int index;
+
+ if (dev->depth == clientCon->rdp_bpp)
+ {
+ memcpy(dst, src, num_pixels * dev->Bpp);
+ return 0;
+ }
+
+ if (dev->depth == 24)
+ {
+ src32 = (unsigned int *)src;
+
+ if (clientCon->rdp_bpp == 24)
+ {
+ dst32 = (unsigned int *)dst;
+
+ for (index = 0; index < num_pixels; index++)
+ {
+ pixel = *src32;
+ *dst32 = pixel;
+ dst32++;
+ src32++;
+ }
+ }
+ else if (clientCon->rdp_bpp == 16)
+ {
+ dst16 = (unsigned short *)dst;
+
+ for (index = 0; index < num_pixels; index++)
+ {
+ pixel = *src32;
+ SPLITCOLOR32(red, green, blue, pixel);
+ pixel = COLOR16(red, green, blue);
+ *dst16 = pixel;
+ dst16++;
+ src32++;
+ }
+ }
+ else if (clientCon->rdp_bpp == 15)
+ {
+ dst16 = (unsigned short *)dst;
+
+ for (index = 0; index < num_pixels; index++)
+ {
+ pixel = *src32;
+ SPLITCOLOR32(red, green, blue, pixel);
+ pixel = COLOR15(red, green, blue);
+ *dst16 = pixel;
+ dst16++;
+ src32++;
+ }
+ }
+ else if (clientCon->rdp_bpp == 8)
+ {
+ dst8 = (unsigned char *)dst;
+
+ for (index = 0; index < num_pixels; index++)
+ {
+ pixel = *src32;
+ SPLITCOLOR32(red, green, blue, pixel);
+ pixel = COLOR8(red, green, blue);
+ *dst8 = pixel;
+ dst8++;
+ src32++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConAlphaPixels(void* src, void* dst, int num_pixels)
+{
+ unsigned int* src32;
+ unsigned char* dst8;
+ int index;
+
+ src32 = (unsigned int*)src;
+ dst8 = (unsigned char*)dst;
+ for (index = 0; index < num_pixels; index++)
+ {
+ *dst8 = (*src32) >> 24;
+ dst8++;
+ src32++;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetFgcolor(rdpPtr dev, rdpClientCon *clientCon, int fgcolor)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetFgcolor:"));
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 12); /* set fgcolor */
+ out_uint16_le(clientCon->out_s, 8); /* size */
+ clientCon->count++;
+ fgcolor = fgcolor & dev->Bpp_mask;
+ fgcolor = rdpClientConConvertPixel(dev, clientCon, fgcolor) &
+ clientCon->rdp_Bpp_mask;
+ out_uint32_le(clientCon->out_s, fgcolor);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetBgcolor(rdpPtr dev, rdpClientCon *clientCon, int bgcolor)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetBgcolor:"));
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 13); /* set bg color */
+ out_uint16_le(clientCon->out_s, 8); /* size */
+ clientCon->count++;
+ bgcolor = bgcolor & dev->Bpp_mask;
+ bgcolor = rdpClientConConvertPixel(dev, clientCon, bgcolor) &
+ clientCon->rdp_Bpp_mask;
+ out_uint32_le(clientCon->out_s, bgcolor);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetOpcode(rdpPtr dev, rdpClientCon *clientCon, int opcode)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetOpcode:"));
+ rdpClientConPreCheck(dev, clientCon, 6);
+ out_uint16_le(clientCon->out_s, 14); /* set opcode */
+ out_uint16_le(clientCon->out_s, 6); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, g_rdp_opcodes[opcode & 0xf]);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetPen(rdpPtr dev, rdpClientCon *clientCon, int style, int width)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetPen:"));
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 17); /* set pen */
+ out_uint16_le(clientCon->out_s, 8); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, style);
+ out_uint16_le(clientCon->out_s, width);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConDrawLine(rdpPtr dev, rdpClientCon *clientCon,
+ short x1, short y1, short x2, short y2)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConDrawLine:"));
+ rdpClientConPreCheck(dev, clientCon, 12);
+ out_uint16_le(clientCon->out_s, 18); /* draw line */
+ out_uint16_le(clientCon->out_s, 12); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, x1);
+ out_uint16_le(clientCon->out_s, y1);
+ out_uint16_le(clientCon->out_s, x2);
+ out_uint16_le(clientCon->out_s, y2);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetCursor(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, char *cur_data, char *cur_mask)
+{
+ int size;
+
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetCursor:"));
+ size = 8 + 32 * (32 * 3) + 32 * (32 / 8);
+ rdpClientConPreCheck(dev, clientCon, size);
+ out_uint16_le(clientCon->out_s, 19); /* set cursor */
+ out_uint16_le(clientCon->out_s, size); /* size */
+ clientCon->count++;
+ x = RDPMAX(0, x);
+ x = RDPMIN(31, x);
+ y = RDPMAX(0, y);
+ y = RDPMIN(31, y);
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint8a(clientCon->out_s, cur_data, 32 * (32 * 3));
+ out_uint8a(clientCon->out_s, cur_mask, 32 * (32 / 8));
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetCursorEx(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, char *cur_data,
+ char *cur_mask, int bpp)
+{
+ int size;
+ int Bpp;
+
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetCursorEx:"));
+ Bpp = (bpp == 0) ? 3 : (bpp + 7) / 8;
+ size = 10 + 32 * (32 * Bpp) + 32 * (32 / 8);
+ rdpClientConPreCheck(dev, clientCon, size);
+ out_uint16_le(clientCon->out_s, 51); /* set cursor ex */
+ out_uint16_le(clientCon->out_s, size); /* size */
+ clientCon->count++;
+ x = RDPMAX(0, x);
+ x = RDPMIN(31, x);
+ y = RDPMAX(0, y);
+ y = RDPMIN(31, y);
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint16_le(clientCon->out_s, bpp);
+ out_uint8a(clientCon->out_s, cur_data, 32 * (32 * Bpp));
+ out_uint8a(clientCon->out_s, cur_mask, 32 * (32 / 8));
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConCreateOsSurface(rdpPtr dev, rdpClientCon *clientCon,
+ int rdpindex, int width, int height)
+{
+ LLOGLN(10, ("rdpClientConCreateOsSurface:"));
+
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConCreateOsSurface: width %d height %d", width, height));
+ rdpClientConPreCheck(dev, clientCon, 12);
+ out_uint16_le(clientCon->out_s, 20);
+ out_uint16_le(clientCon->out_s, 12);
+ clientCon->count++;
+ out_uint32_le(clientCon->out_s, rdpindex);
+ out_uint16_le(clientCon->out_s, width);
+ out_uint16_le(clientCon->out_s, height);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConCreateOsSurfaceBpp(rdpPtr dev, rdpClientCon *clientCon,
+ int rdpindex, int width, int height, int bpp)
+{
+ LLOGLN(10, ("rdpClientConCreateOsSurfaceBpp:"));
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConCreateOsSurfaceBpp: width %d height %d "
+ "bpp %d", width, height, bpp));
+ rdpClientConPreCheck(dev, clientCon, 13);
+ out_uint16_le(clientCon->out_s, 31);
+ out_uint16_le(clientCon->out_s, 13);
+ clientCon->count++;
+ out_uint32_le(clientCon->out_s, rdpindex);
+ out_uint16_le(clientCon->out_s, width);
+ out_uint16_le(clientCon->out_s, height);
+ out_uint8(clientCon->out_s, bpp);
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSwitchOsSurface(rdpPtr dev, rdpClientCon *clientCon, int rdpindex)
+{
+ LLOGLN(10, ("rdpClientConSwitchOsSurface:"));
+
+ if (clientCon->connected)
+ {
+ if (clientCon->rdpIndex == rdpindex)
+ {
+ return 0;
+ }
+
+ clientCon->rdpIndex = rdpindex;
+ LLOGLN(10, ("rdpClientConSwitchOsSurface: rdpindex %d", rdpindex));
+ /* switch surface */
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 21);
+ out_uint16_le(clientCon->out_s, 8);
+ out_uint32_le(clientCon->out_s, rdpindex);
+ clientCon->count++;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConDeleteOsSurface(rdpPtr dev, rdpClientCon *clientCon, int rdpindex)
+{
+ LLOGLN(10, ("rdpClientConDeleteOsSurface: rdpindex %d", rdpindex));
+
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConDeleteOsSurface: rdpindex %d", rdpindex));
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 22);
+ out_uint16_le(clientCon->out_s, 8);
+ clientCon->count++;
+ out_uint32_le(clientCon->out_s, rdpindex);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns -1 on error */
+int
+rdpClientConAddOsBitmap(rdpPtr dev, rdpClientCon *clientCon,
+ PixmapPtr pixmap, rdpPixmapPtr priv)
+{
+ int index;
+ int rv;
+ int oldest;
+ int oldest_index;
+ int this_bytes;
+
+ LLOGLN(10, ("rdpClientConAddOsBitmap:"));
+ if (clientCon->connected == FALSE)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: test error 1"));
+ return -1;
+ }
+
+ if (clientCon->osBitmaps == NULL)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: test error 2"));
+ return -1;
+ }
+
+ this_bytes = pixmap->devKind * pixmap->drawable.height;
+ if (this_bytes > MAX_OS_BYTES)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: error, too big this_bytes %d "
+ "width %d height %d", this_bytes,
+ pixmap->drawable.height, pixmap->drawable.height));
+ return -1;
+ }
+
+ oldest = 0x7fffffff;
+ oldest_index = -1;
+ rv = -1;
+ index = 0;
+
+ while (index < clientCon->maxOsBitmaps)
+ {
+ if (clientCon->osBitmaps[index].used == FALSE)
+ {
+ clientCon->osBitmaps[index].used = TRUE;
+ clientCon->osBitmaps[index].pixmap = pixmap;
+ clientCon->osBitmaps[index].priv = priv;
+ clientCon->osBitmaps[index].stamp = clientCon->osBitmapStamp;
+ clientCon->osBitmapStamp++;
+ clientCon->osBitmapNumUsed++;
+ rv = index;
+ break;
+ }
+ else
+ {
+ if (clientCon->osBitmaps[index].stamp < oldest)
+ {
+ oldest = clientCon->osBitmaps[index].stamp;
+ oldest_index = index;
+ }
+ }
+ index++;
+ }
+
+ if (rv == -1)
+ {
+ if (oldest_index == -1)
+ {
+ LLOGLN(0, ("rdpClientConAddOsBitmap: error"));
+ }
+ else
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: too many pixmaps removing "
+ "oldest_index %d", oldest_index));
+ rdpClientConRemoveOsBitmap(dev, clientCon, oldest_index);
+ rdpClientConDeleteOsSurface(dev, clientCon, oldest_index);
+ clientCon->osBitmaps[oldest_index].used = TRUE;
+ clientCon->osBitmaps[oldest_index].pixmap = pixmap;
+ clientCon->osBitmaps[oldest_index].priv = priv;
+ clientCon->osBitmaps[oldest_index].stamp = clientCon->osBitmapStamp;
+ clientCon->osBitmapStamp++;
+ clientCon->osBitmapNumUsed++;
+ rv = oldest_index;
+ }
+ }
+
+ if (rv < 0)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: test error 3"));
+ return rv;
+ }
+
+ clientCon->osBitmapAllocSize += this_bytes;
+ LLOGLN(10, ("rdpClientConAddOsBitmap: this_bytes %d "
+ "clientCon->osBitmapAllocSize %d",
+ this_bytes, clientCon->osBitmapAllocSize));
+#if USE_MAX_OS_BYTES
+ while (clientCon->osBitmapAllocSize > MAX_OS_BYTES)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: must delete "
+ "clientCon->osBitmapNumUsed %d",
+ clientCon->osBitmapNumUsed));
+ /* find oldest */
+ oldest = 0x7fffffff;
+ oldest_index = -1;
+ index = 0;
+ while (index < clientCon->maxOsBitmaps)
+ {
+ if (clientCon->osBitmaps[index].used &&
+ (clientCon->osBitmaps[index].stamp < oldest))
+ {
+ oldest = clientCon->osBitmaps[index].stamp;
+ oldest_index = index;
+ }
+ index++;
+ }
+ if (oldest_index == -1)
+ {
+ LLOGLN(0, ("rdpClientConAddOsBitmap: error 1"));
+ break;
+ }
+ if (oldest_index == rv)
+ {
+ LLOGLN(0, ("rdpClientConAddOsBitmap: error 2"));
+ break;
+ }
+ rdpClientConRemoveOsBitmap(dev, clientCon, oldest_index);
+ rdpClientConDeleteOsSurface(dev, clientCon, oldest_index);
+ }
+#endif
+ LLOGLN(10, ("rdpClientConAddOsBitmap: new bitmap index %d", rv));
+ LLOGLN(10, ("rdpClientConAddOsBitmap: clientCon->osBitmapNumUsed %d "
+ "clientCon->osBitmapStamp 0x%8.8x",
+ clientCon->osBitmapNumUsed, clientCon->osBitmapStamp));
+ return rv;
+}
+
+/*****************************************************************************/
+int
+rdpClientConRemoveOsBitmap(rdpPtr dev, rdpClientCon *clientCon, int rdpindex)
+{
+ PixmapPtr pixmap;
+ rdpPixmapPtr priv;
+ int this_bytes;
+
+ if (clientCon->osBitmaps == NULL)
+ {
+ LLOGLN(10, ("rdpClientConRemoveOsBitmap: test error 1"));
+ return 1;
+ }
+
+ LLOGLN(10, ("rdpClientConRemoveOsBitmap: index %d stamp %d",
+ rdpindex, clientCon->osBitmaps[rdpindex].stamp));
+
+ if ((rdpindex < 0) && (rdpindex >= clientCon->maxOsBitmaps))
+ {
+ LLOGLN(10, ("rdpClientConRemoveOsBitmap: test error 2"));
+ return 1;
+ }
+
+ if (clientCon->osBitmaps[rdpindex].used)
+ {
+ pixmap = clientCon->osBitmaps[rdpindex].pixmap;
+ priv = clientCon->osBitmaps[rdpindex].priv;
+ rdpDrawItemRemoveAll(dev, priv);
+ this_bytes = pixmap->devKind * pixmap->drawable.height;
+ clientCon->osBitmapAllocSize -= this_bytes;
+ LLOGLN(10, ("rdpClientConRemoveOsBitmap: this_bytes %d "
+ "clientCon->osBitmapAllocSize %d", this_bytes,
+ clientCon->osBitmapAllocSize));
+ clientCon->osBitmaps[rdpindex].used = 0;
+ clientCon->osBitmaps[rdpindex].pixmap = 0;
+ clientCon->osBitmaps[rdpindex].priv = 0;
+ clientCon->osBitmapNumUsed--;
+ priv->status = 0;
+ priv->con_number = 0;
+ priv->use_count = 0;
+ }
+ else
+ {
+ LLOGLN(0, ("rdpup_remove_os_bitmap: error"));
+ }
+
+ LLOGLN(10, ("rdpup_remove_os_bitmap: clientCon->osBitmapNumUsed %d",
+ clientCon->osBitmapNumUsed));
+ return 0;
+}
+
+/*****************************************************************************/
+int
+rdpClientConUpdateOsUse(rdpPtr dev, rdpClientCon *clientCon, int rdpindex)
+{
+ if (clientCon->osBitmaps == NULL)
+ {
+ return 1;
+ }
+
+ LLOGLN(10, ("rdpClientConUpdateOsUse: index %d stamp %d",
+ rdpindex, clientCon->osBitmaps[rdpindex].stamp));
+
+ if ((rdpindex < 0) && (rdpindex >= clientCon->maxOsBitmaps))
+ {
+ return 1;
+ }
+
+ if (clientCon->osBitmaps[rdpindex].used)
+ {
+ clientCon->osBitmaps[rdpindex].stamp = clientCon->osBitmapStamp;
+ clientCon->osBitmapStamp++;
+ }
+ else
+ {
+ LLOGLN(0, ("rdpClientConUpdateOsUse: error rdpindex %d", rdpindex));
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int
+rdpClientConSend(rdpPtr dev, rdpClientCon *clientCon, char *data, int len)
+{
+ int sent;
+
+ LLOGLN(10, ("rdpClientConSend - sending %d bytes", len));
+
+ if (clientCon->sckClosed)
+ {
+ return 1;
+ }
+
+ while (len > 0)
+ {
+ sent = g_sck_send(clientCon->sck, data, len, 0);
+
+ if (sent == -1)
+ {
+ if (g_sck_last_error_would_block(clientCon->sck))
+ {
+ g_sleep(1);
+ }
+ else
+ {
+ LLOGLN(0, ("rdpClientConSend: g_tcp_send failed(returned -1)"));
+ rdpClientConDisconnect(dev, clientCon);
+ return 1;
+ }
+ }
+ else if (sent == 0)
+ {
+ LLOGLN(0, ("rdpClientConSend: g_tcp_send failed(returned zero)"));
+ rdpClientConDisconnect(dev, clientCon);
+ return 1;
+ }
+ else
+ {
+ data += sent;
+ len -= sent;
+ }
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+static int
+rdpClientConSendMsg(rdpPtr dev, rdpClientCon *clientCon)
+{
+ int len;
+ int rv;
+ struct stream *s;
+
+ rv = 1;
+ s = clientCon->out_s;
+ if (s != NULL)
+ {
+ len = (int) (s->end - s->data);
+
+ if (len > s->size)
+ {
+ LLOGLN(0, ("rdpClientConSendMsg: overrun error len %d count %d",
+ len, clientCon->count));
+ }
+
+ s_pop_layer(s, iso_hdr);
+ out_uint16_le(s, 3);
+ out_uint16_le(s, clientCon->count);
+ out_uint32_le(s, len - 8);
+ rv = rdpClientConSend(dev, clientCon, s->data, len);
+ }
+
+ if (rv != 0)
+ {
+ LLOGLN(0, ("rdpClientConSendMsg: error in rdpup_send_msg"));
+ }
+
+ return rv;
+}
+
+/******************************************************************************/
+static int
+rdpClientConSendPending(rdpPtr dev, rdpClientCon *clientCon)
+{
+ int rv;
+
+ rv = 0;
+ if (clientCon->connected && clientCon->begin)
+ {
+ out_uint16_le(clientCon->out_s, 2); /* XR_SERVER_END_UPDATE */
+ out_uint16_le(clientCon->out_s, 4); /* size */
+ clientCon->count++;
+ s_mark_end(clientCon->out_s);
+ if (rdpClientConSendMsg(dev, clientCon) != 0)
+ {
+ LLOGLN(0, ("rdpClientConSendPending: rdpClientConSendMsg failed"));
+ rv = 1;
+ }
+ }
+ clientCon->count = 0;
+ clientCon->begin = FALSE;
+ return rv;
+}
+
+/******************************************************************************/
+static CARD32
+rdpClientConDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ rdpPtr dev;
+ rdpClientCon *clientCon;
+
+ LLOGLN(10, ("rdpClientConDeferredUpdateCallback"));
+
+ dev = (rdpPtr) arg;
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ if (dev->do_dirty_ons)
+ {
+ if (clientCon->rectId == clientCon->rectIdAck)
+ {
+ rdpClientConCheckDirtyScreen(dev, clientCon);
+ }
+ else
+ {
+ LLOGLN(0, ("rdpClientConDeferredUpdateCallback: skipping"));
+ }
+ }
+ else
+ {
+ rdpClientConSendPending(dev, clientCon);
+ }
+ clientCon = clientCon->next;
+ }
+ dev->sendUpdateScheduled = FALSE;
+ return 0;
+}
+
+/******************************************************************************/
+void
+rdpClientConScheduleDeferredUpdate(rdpPtr dev)
+{
+ if (dev->sendUpdateScheduled == FALSE)
+ {
+ dev->sendUpdateScheduled = TRUE;
+ dev->sendUpdateTimer = TimerSet(dev->sendUpdateTimer, 0, 40,
+ rdpClientConDeferredUpdateCallback,
+ dev);
+ }
+}
+
+/******************************************************************************/
+int
+rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon)
+{
+ return 0;
+}
diff --git a/xorg/server/module/rdpClientCon.h b/xorg/server/module/rdpClientCon.h
index 85a3925a..f288fd7c 100644
--- a/xorg/server/module/rdpClientCon.h
+++ b/xorg/server/module/rdpClientCon.h
@@ -24,6 +24,15 @@ Client connection to xrdp
#ifndef _RDPCLIENTCON_H
#define _RDPCLIENTCON_H
+struct rdpup_os_bitmap
+{
+ int used;
+ PixmapPtr pixmap;
+ rdpPixmapPtr priv;
+ int stamp;
+};
+
+/* one of these for each client */
struct _rdpClientCon
{
int sck;
@@ -31,6 +40,24 @@ struct _rdpClientCon
int sckControl;
struct stream *out_s;
struct stream *in_s;
+
+ int rectIdAck;
+ int rectId;
+ int connected; /* boolean */
+ int begin; /* boolean */
+ int count;
+ int sckClosed; /* boolean */
+ struct rdpup_os_bitmap *osBitmaps;
+ int maxOsBitmaps;
+ int osBitmapStamp;
+ int osBitmapAllocSize;
+ int osBitmapNumUsed;
+
+ int rdp_bpp; /* client depth */
+ int rdp_Bpp_mask;
+
+ int rdpIndex; /* current os target */
+
struct _rdpClientCon *next;
};
@@ -41,4 +68,16 @@ rdpClientConInit(rdpPtr dev);
int
rdpClientConDeinit(rdpPtr dev);
+int
+rdpClientConDeleteOsSurface(rdpPtr dev, rdpClientCon *clientCon, int rdpindex);
+
+int
+rdpClientConRemoveOsBitmap(rdpPtr dev, rdpClientCon *clientCon, int rdpindex);
+
+void
+rdpClientConScheduleDeferredUpdate(rdpPtr dev);
+int
+rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon);
+
+
#endif
diff --git a/xorg/server/module/rdpDraw.c b/xorg/server/module/rdpDraw.c
index 08fe4b85..cbb7ce75 100644
--- a/xorg/server/module/rdpDraw.c
+++ b/xorg/server/module/rdpDraw.c
@@ -39,11 +39,100 @@ misc draw calls
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpMisc.h"
+#include "rdpGlyphs.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
+/******************************************************************************/
+int
+rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di)
+{
+ priv->is_alpha_dirty_not = FALSE;
+
+ if (priv->draw_item_tail == NULL)
+ {
+ priv->draw_item_tail = di;
+ priv->draw_item_head = di;
+ }
+ else
+ {
+ di->prev = priv->draw_item_tail;
+ priv->draw_item_tail->next = di;
+ priv->draw_item_tail = di;
+ }
+
+ if (priv == &(dev->screenPriv))
+ {
+ rdpClientConScheduleDeferredUpdate(dev);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpDrawItemRemove(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di)
+{
+ if (di->prev != NULL)
+ {
+ di->prev->next = di->next;
+ }
+
+ if (di->next != NULL)
+ {
+ di->next->prev = di->prev;
+ }
+
+ if (priv->draw_item_head == di)
+ {
+ priv->draw_item_head = di->next;
+ }
+
+ if (priv->draw_item_tail == di)
+ {
+ priv->draw_item_tail = di->prev;
+ }
+
+ if (di->type == RDI_LINE)
+ {
+ if (di->u.line.segs != NULL)
+ {
+ g_free(di->u.line.segs);
+ }
+ }
+
+ if (di->type == RDI_TEXT)
+ {
+ rdpGlyphDeleteRdpText(di->u.text.rtext);
+ }
+
+ rdpRegionDestroy(di->reg);
+ g_free(di);
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpDrawItemRemoveAll(rdpPtr dev, rdpPixmapRec *priv)
+{
+ struct rdp_draw_item *di;
+
+ di = priv->draw_item_head;
+
+ while (di != NULL)
+ {
+ rdpDrawItemRemove(dev, priv, di);
+ di = priv->draw_item_head;
+ }
+
+ return 0;
+}
+
/*****************************************************************************/
void
rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
diff --git a/xorg/server/module/rdpDraw.h b/xorg/server/module/rdpDraw.h
index e2711768..2f4aea2f 100644
--- a/xorg/server/module/rdpDraw.h
+++ b/xorg/server/module/rdpDraw.h
@@ -50,6 +50,12 @@ do { \
extern GCOps g_rdpGCOps; /* in rdpGC.c */
+int
+rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di);
+int
+rdpDrawItemRemove(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di);
+int
+rdpDrawItemRemoveAll(rdpPtr dev, rdpPixmapRec *priv);
void
rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion);
Bool
diff --git a/xorg/server/module/rdpGlyphs.c b/xorg/server/module/rdpGlyphs.c
index fc2d347b..71e8a660 100644
--- a/xorg/server/module/rdpGlyphs.c
+++ b/xorg/server/module/rdpGlyphs.c
@@ -38,6 +38,8 @@ gylph(font) calls
#include "rdp.h"
#include "rdpGlyphs.h"
#include "rdpDraw.h"
+#include "rdpMisc.h"
+#include "rdpReg.h"
/******************************************************************************/
#define LOG_LEVEL 1
@@ -45,6 +47,30 @@ gylph(font) calls
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
+int
+rdpGlyphDeleteRdpText(struct rdp_text *rtext)
+{
+ int index;
+
+ if (rtext == NULL)
+ {
+ return 0;
+ }
+ for (index = 0; index < rtext->num_chars; index++)
+ {
+ if (rtext->chars[index] != NULL)
+ {
+ g_free(rtext->chars[index]->data);
+ g_free(rtext->chars[index]);
+ }
+ }
+ rdpRegionDestroy(rtext->reg);
+ rdpGlyphDeleteRdpText(rtext->next);
+ g_free(rtext);
+ return 0;
+}
+
+/******************************************************************************/
static void
rdpGlyphsOrg(PictureScreenPtr ps, rdpPtr dev,
CARD8 op, PicturePtr pSrc, PicturePtr pDst,
diff --git a/xorg/server/module/rdpGlyphs.h b/xorg/server/module/rdpGlyphs.h
index d451d9f9..24e978a1 100644
--- a/xorg/server/module/rdpGlyphs.h
+++ b/xorg/server/module/rdpGlyphs.h
@@ -24,6 +24,35 @@ gylph(font) calls
#ifndef _RDPGLYPHS_H
#define _RDPGLYPHS_H
+struct rdp_font_char
+{
+ int offset; /* x */
+ int baseline; /* y */
+ int width; /* cx */
+ int height; /* cy */
+ int incby;
+ int bpp;
+ char *data;
+ int data_bytes;
+};
+
+struct rdp_text
+{
+ RegionPtr reg;
+ int font;
+ int x;
+ int y;
+ int flags;
+ int mixmode;
+ char data[256];
+ int data_bytes;
+ struct rdp_font_char* chars[256];
+ int num_chars;
+ struct rdp_text* next;
+};
+
+int
+rdpGlyphDeleteRdpText(struct rdp_text* rtext);
void
rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
diff --git a/xorg/server/module/rdpMisc.c b/xorg/server/module/rdpMisc.c
index 34e71110..326deff3 100644
--- a/xorg/server/module/rdpMisc.c
+++ b/xorg/server/module/rdpMisc.c
@@ -67,14 +67,14 @@ rdpBitsPerPixel(int depth)
/*****************************************************************************/
int
-g_tcp_recv(int sck, void *ptr, int len, int flags)
+g_sck_recv(int sck, void *ptr, int len, int flags)
{
return recv(sck, ptr, len, flags);
}
/*****************************************************************************/
void
-g_tcp_close(int sck)
+g_sck_close(int sck)
{
if (sck == 0)
{
@@ -87,7 +87,7 @@ g_tcp_close(int sck)
/*****************************************************************************/
int
-g_tcp_last_error_would_block(int sck)
+g_sck_last_error_would_block(int sck)
{
return (errno == EWOULDBLOCK) || (errno == EINPROGRESS);
}
@@ -101,7 +101,7 @@ g_sleep(int msecs)
/*****************************************************************************/
int
-g_tcp_send(int sck, void *ptr, int len, int flags)
+g_sck_send(int sck, void *ptr, int len, int flags)
{
return send(sck, ptr, len, flags);
}
@@ -146,7 +146,7 @@ g_sprintf(char *dest, char *format, ...)
/*****************************************************************************/
int
-g_tcp_socket(void)
+g_sck_tcp_socket(void)
{
int rv;
int i;
@@ -160,14 +160,14 @@ g_tcp_socket(void)
/*****************************************************************************/
int
-g_tcp_local_socket_dgram(void)
+g_sck_local_socket_dgram(void)
{
return socket(AF_UNIX, SOCK_DGRAM, 0);
}
/*****************************************************************************/
int
-g_tcp_local_socket_stream(void)
+g_sck_local_socket_stream(void)
{
return socket(AF_UNIX, SOCK_STREAM, 0);
}
@@ -188,7 +188,7 @@ g_memset(void *d_ptr, const unsigned char chr, int size)
/*****************************************************************************/
int
-g_tcp_set_no_delay(int sck)
+g_sck_tcp_set_no_delay(int sck)
{
int i;
@@ -199,7 +199,7 @@ g_tcp_set_no_delay(int sck)
/*****************************************************************************/
int
-g_tcp_set_non_blocking(int sck)
+g_sck_set_non_blocking(int sck)
{
unsigned long i;
@@ -211,7 +211,7 @@ g_tcp_set_non_blocking(int sck)
/*****************************************************************************/
int
-g_tcp_accept(int sck)
+g_sck_accept(int sck)
{
struct sockaddr_in s;
unsigned int i;
@@ -223,7 +223,7 @@ g_tcp_accept(int sck)
/*****************************************************************************/
int
-g_tcp_select(int sck1, int sck2, int sck3)
+g_sck_select(int sck1, int sck2, int sck3)
{
fd_set rfds;
struct timeval time;
@@ -292,7 +292,7 @@ g_tcp_select(int sck1, int sck2, int sck3)
/*****************************************************************************/
int
-g_tcp_bind(int sck, char *port)
+g_sck_tcp_bind(int sck, char *port)
{
struct sockaddr_in s;
@@ -305,7 +305,7 @@ g_tcp_bind(int sck, char *port)
/*****************************************************************************/
int
-g_tcp_local_bind(int sck, char *port)
+g_sck_local_bind(int sck, char *port)
{
struct sockaddr_un s;
@@ -317,7 +317,7 @@ g_tcp_local_bind(int sck, char *port)
/*****************************************************************************/
int
-g_tcp_listen(int sck)
+g_sck_listen(int sck)
{
return listen(sck, 2);
}
diff --git a/xorg/server/module/rdpMisc.h b/xorg/server/module/rdpMisc.h
index bed95891..ff54dc0e 100644
--- a/xorg/server/module/rdpMisc.h
+++ b/xorg/server/module/rdpMisc.h
@@ -29,15 +29,15 @@ the rest
int
rdpBitsPerPixel(int depth);
int
-g_tcp_recv(int sck, void *ptr, int len, int flags);
+g_sck_recv(int sck, void *ptr, int len, int flags);
void
-g_tcp_close(int sck);
+g_sck_close(int sck);
int
-g_tcp_last_error_would_block(int sck);
+g_sck_last_error_would_block(int sck);
void
g_sleep(int msecs);
int
-g_tcp_send(int sck, void *ptr, int len, int flags);
+g_sck_send(int sck, void *ptr, int len, int flags);
void *
g_malloc(int size, int zero);
void
@@ -45,29 +45,29 @@ g_free(void *ptr);
void
g_sprintf(char *dest, char *format, ...);
int
-g_tcp_socket(void);
+g_sck_tcp_socket(void);
int
-g_tcp_local_socket_dgram(void);
+g_sck_local_socket_dgram(void);
int
-g_tcp_local_socket_stream(void);
+g_sck_local_socket_stream(void);
void
g_memcpy(void *d_ptr, const void *s_ptr, int size);
void
g_memset(void *d_ptr, const unsigned char chr, int size);
int
-g_tcp_set_no_delay(int sck);
+g_sck_tcp_set_no_delay(int sck);
int
-g_tcp_set_non_blocking(int sck);
+g_sck_set_non_blocking(int sck);
int
-g_tcp_accept(int sck);
+g_sck_accept(int sck);
int
-g_tcp_select(int sck1, int sck2, int sck3);
+g_sck_select(int sck1, int sck2, int sck3);
int
-g_tcp_bind(int sck, char *port);
+g_sck_tcp_bind(int sck, char *port);
int
-g_tcp_local_bind(int sck, char *port);
+g_sck_local_bind(int sck, char *port);
int
-g_tcp_listen(int sck);
+g_sck_listen(int sck);
int
g_create_dir(const char *dirname);
int
@@ -87,7 +87,6 @@ g_hexdump(unsigned char *p, unsigned int len);
# error Unknown endianness in rdp.h
#endif
/* check if we need to align data */
-/* check if we need to align data */
#if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \
defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \
defined(__ia64__) || defined(__ppc__) || defined(__arm__)
@@ -97,157 +96,164 @@ g_hexdump(unsigned char *p, unsigned int len);
/* parser state */
struct stream
{
- char* p;
- char* end;
- char* data;
- int size;
- /* offsets of various headers */
- char* iso_hdr;
- char* mcs_hdr;
- char* sec_hdr;
- char* rdp_hdr;
- char* channel_hdr;
- char* next_packet;
+ char *p;
+ char *end;
+ char *data;
+ int size;
+ /* offsets of various headers */
+ char *iso_hdr;
+ char *mcs_hdr;
+ char *sec_hdr;
+ char *rdp_hdr;
+ char *channel_hdr;
+ char *next_packet;
};
/******************************************************************************/
#define s_push_layer(s, h, n) \
-{ \
- (s)->h = (s)->p; \
- (s)->p += (n); \
-}
+do { \
+ (s)->h = (s)->p; \
+ (s)->p += (n); \
+} while (0)
/******************************************************************************/
#define s_pop_layer(s, h) \
-{ \
- (s)->p = (s)->h; \
-}
+do { \
+ (s)->p = (s)->h; \
+} while (0)
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
-#define out_uint16_le(s, v) \
-{ \
- *((s)->p) = (unsigned char)((v) >> 0); \
- (s)->p++; \
- *((s)->p) = (unsigned char)((v) >> 8); \
- (s)->p++; \
-}
+#define out_uint16_le(s, v) \
+do { \
+ *((s)->p) = (unsigned char)((v) >> 0); \
+ (s)->p++; \
+ *((s)->p) = (unsigned char)((v) >> 8); \
+ (s)->p++; \
+} while (0)
#else
-#define out_uint16_le(s, v) \
-{ \
- *((unsigned short*)((s)->p)) = (unsigned short)(v); \
- (s)->p += 2; \
-}
+#define out_uint16_le(s, v) \
+do { \
+ *((unsigned short*)((s)->p)) = (unsigned short)(v); \
+ (s)->p += 2; \
+} while (0)
#endif
/******************************************************************************/
-#define init_stream(s, v) \
-{ \
- if ((v) > (s)->size) \
- { \
- g_free((s)->data); \
- (s)->data = (char*)g_malloc((v), 0); \
- (s)->size = (v); \
- } \
- (s)->p = (s)->data; \
- (s)->end = (s)->data; \
- (s)->next_packet = 0; \
-}
+#define init_stream(s, v) \
+do { \
+ if ((v) > (s)->size) \
+ { \
+ g_free((s)->data); \
+ (s)->data = (char*)g_malloc((v), 0); \
+ (s)->size = (v); \
+ } \
+ (s)->p = (s)->data; \
+ (s)->end = (s)->data; \
+ (s)->next_packet = 0; \
+} while (0)
/******************************************************************************/
-#define out_uint8p(s, v, n) \
-{ \
- g_memcpy((s)->p, (v), (n)); \
- (s)->p += (n); \
-}
+#define out_uint8p(s, v, n) \
+do { \
+ g_memcpy((s)->p, (v), (n)); \
+ (s)->p += (n); \
+} while (0)
/******************************************************************************/
-#define out_uint8a(s, v, n) \
-{ \
- out_uint8p((s), (v), (n)); \
-}
+#define out_uint8a(s, v, n) \
+do { \
+ out_uint8p((s), (v), (n)); \
+} while (0)
+
+/******************************************************************************/
+#define out_uint8(s, v) \
+do { \
+ *((s)->p) = (unsigned char)((v) >> 0); \
+ (s)->p++; \
+} while (0)
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
-#define out_uint32_le(s, v) \
-{ \
- *((s)->p) = (unsigned char)((v) >> 0); \
- (s)->p++; \
- *((s)->p) = (unsigned char)((v) >> 8); \
- (s)->p++; \
- *((s)->p) = (unsigned char)((v) >> 16); \
- (s)->p++; \
- *((s)->p) = (unsigned char)((v) >> 24); \
- (s)->p++; \
-}
+#define out_uint32_le(s, v) \
+do { \
+ *((s)->p) = (unsigned char)((v) >> 0); \
+ (s)->p++; \
+ *((s)->p) = (unsigned char)((v) >> 8); \
+ (s)->p++; \
+ *((s)->p) = (unsigned char)((v) >> 16); \
+ (s)->p++; \
+ *((s)->p) = (unsigned char)((v) >> 24); \
+ (s)->p++; \
+} while (0)
#else
-#define out_uint32_le(s, v) \
-{ \
- *((unsigned int*)((s)->p)) = (v); \
- (s)->p += 4; \
-}
+#define out_uint32_le(s, v) \
+do { \
+ *((unsigned int*)((s)->p)) = (v); \
+ (s)->p += 4; \
+} while (0)
#endif
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
-#define in_uint32_le(s, v) \
-{ \
- (v) = (unsigned int) \
- ( \
- (*((unsigned char*)((s)->p + 0)) << 0) | \
- (*((unsigned char*)((s)->p + 1)) << 8) | \
- (*((unsigned char*)((s)->p + 2)) << 16) | \
- (*((unsigned char*)((s)->p + 3)) << 24) \
- ); \
- (s)->p += 4; \
-}
+#define in_uint32_le(s, v) \
+do { \
+ (v) = (unsigned int) \
+ ( \
+ (*((unsigned char*)((s)->p + 0)) << 0) | \
+ (*((unsigned char*)((s)->p + 1)) << 8) | \
+ (*((unsigned char*)((s)->p + 2)) << 16) | \
+ (*((unsigned char*)((s)->p + 3)) << 24) \
+ ); \
+ (s)->p += 4; \
+} while (0)
#else
-#define in_uint32_le(s, v) \
-{ \
- (v) = *((unsigned int*)((s)->p)); \
- (s)->p += 4; \
-}
+#define in_uint32_le(s, v) \
+do { \
+ (v) = *((unsigned int*)((s)->p)); \
+ (s)->p += 4; \
+} while (0)
#endif
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
-#define in_uint16_le(s, v) \
-{ \
- (v) = (unsigned short) \
- ( \
- (*((unsigned char*)((s)->p + 0)) << 0) | \
- (*((unsigned char*)((s)->p + 1)) << 8) \
- ); \
- (s)->p += 2; \
-}
+#define in_uint16_le(s, v) \
+do { \
+ (v) = (unsigned short) \
+ ( \
+ (*((unsigned char*)((s)->p + 0)) << 0) | \
+ (*((unsigned char*)((s)->p + 1)) << 8) \
+ ); \
+ (s)->p += 2; \
+} while (0)
#else
-#define in_uint16_le(s, v) \
-{ \
- (v) = *((unsigned short*)((s)->p)); \
- (s)->p += 2; \
-}
+#define in_uint16_le(s, v) \
+do { \
+ (v) = *((unsigned short*)((s)->p)); \
+ (s)->p += 2; \
+} while (0)
#endif
/******************************************************************************/
-#define s_mark_end(s) \
-{ \
- (s)->end = (s)->p; \
-}
+#define s_mark_end(s) \
+do { \
+ (s)->end = (s)->p; \
+} while (0)
/******************************************************************************/
-#define make_stream(s) \
-{ \
- (s) = (struct stream*)g_malloc(sizeof(struct stream), 1); \
-}
+#define make_stream(s) \
+do { \
+ (s) = (struct stream*)g_malloc(sizeof(struct stream), 1); \
+} while (0)
/******************************************************************************/
-#define free_stream(s) do \
-{ \
- if ((s) != 0) \
- { \
- g_free((s)->data); \
- } \
- g_free((s)); \
+#define free_stream(s) \
+do { \
+ if ((s) != 0) \
+ { \
+ g_free((s)->data); \
+ } \
+ g_free((s)); \
} while (0)
#endif
diff --git a/xorg/server/module/rdpPolyFillRect.c b/xorg/server/module/rdpPolyFillRect.c
index 1de9cee1..63898e23 100644
--- a/xorg/server/module/rdpPolyFillRect.c
+++ b/xorg/server/module/rdpPolyFillRect.c
@@ -32,6 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -39,6 +40,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/******************************************************************************/
static void
+rdpPolyFillRectPre(rdpClientCon *clientCon,
+ DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+}
+
+/******************************************************************************/
+static void
rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
xRectangle *prectInit)
{
@@ -50,11 +59,35 @@ rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
}
/******************************************************************************/
+static void
+rdpPolyFillRectPost(rdpClientCon *clientCon,
+ DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+}
+
+/******************************************************************************/
void
rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
xRectangle *prectInit)
{
+ rdpPtr dev;
+ rdpClientCon *clientCon;
+
LLOGLN(10, ("rdpPolyFillRect:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ rdpPolyFillRectPre(clientCon, pDrawable, pGC, nrectFill, prectInit);
+ clientCon = clientCon->next;
+ }
/* do original call */
rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ rdpPolyFillRectPost(clientCon, pDrawable, pGC, nrectFill, prectInit);
+ clientCon = clientCon->next;
+ }
}
diff --git a/xrdpvr/xrdpvr.c b/xrdpvr/xrdpvr.c
index 09a0a6b8..46326e9e 100644
--- a/xrdpvr/xrdpvr.c
+++ b/xrdpvr/xrdpvr.c
@@ -28,6 +28,49 @@ PLAYER_STATE_INFO g_psi;
int g_video_index = -1;
int g_audio_index = -1;
+/*****************************************************************************/
+/* produce a hex dump */
+void hexdump(char *p, int len)
+{
+ unsigned char *line;
+ int i;
+ int thisline;
+ int offset;
+
+ line = (unsigned char *)p;
+ offset = 0;
+
+ while (offset < len)
+ {
+ printf("%04x ", offset);
+ thisline = len - offset;
+
+ if (thisline > 16)
+ {
+ thisline = 16;
+ }
+
+ for (i = 0; i < thisline; i++)
+ {
+ printf("%02x ", line[i]);
+ }
+
+ for (; i < 16; i++)
+ {
+ printf(" ");
+ }
+
+ for (i = 0; i < thisline; i++)
+ {
+ printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
+ }
+
+ printf("\n");
+ offset += thisline;
+ line += thisline;
+ }
+}
+
/**
* initialize the media player
*
@@ -40,11 +83,15 @@ int g_audio_index = -1;
int
xrdpvr_init_player(void *channel, int stream_id, char *filename)
{
+ printf("xrdpvr_init_player:\n");
if ((channel == NULL) || (stream_id <= 0) || (filename == NULL))
{
return -1;
}
+ xrdpvr_send_init(channel);
+
+#if 0
/* send metadata from media file to client */
if (xrdpvr_create_metadata_file(channel, filename))
{
@@ -68,6 +115,8 @@ xrdpvr_init_player(void *channel, int stream_id, char *filename)
printf("xrdpvr_set_audio_format() failed\n");
return 1;
}
+#endif
+
}
/**
@@ -173,7 +222,7 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
return -1;
}
-#if 0
+#if 1
/* print media info to standard out */
av_dump_format(g_psi.p_format_ctx, 0, filename, 0);
#endif
@@ -182,13 +231,15 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
for (i = 0; i < g_psi.p_format_ctx->nb_streams; i++)
{
if (g_psi.p_format_ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO &&
- g_video_index < 0)
+ g_psi.p_format_ctx->streams[i]->codec->codec_id == CODEC_ID_H264 &&
+ g_video_index < 0)
{
g_video_index = i;
}
if (g_psi.p_format_ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO &&
- g_audio_index < 0)
+ g_psi.p_format_ctx->streams[i]->codec->codec_id == CODEC_ID_AAC &&
+ g_audio_index < 0)
{
g_audio_index = i;
}
@@ -235,6 +286,12 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
return -1;
}
+ printf("%d\n", g_psi.p_audio_codec_ctx->extradata_size);
+ hexdump(g_psi.p_audio_codec_ctx->extradata, g_psi.p_audio_codec_ctx->extradata_size);
+ printf("%d %d %d %d\n", g_psi.p_audio_codec_ctx->sample_rate,
+ g_psi.p_audio_codec_ctx->bit_rate, g_psi.p_audio_codec_ctx->channels,
+ g_psi.p_audio_codec_ctx->block_align);
+
/* open decoder for video stream */
//if (avcodec_open2(g_psi.p_video_codec_ctx, g_psi.p_video_codec,
// NULL) < 0)
@@ -244,17 +301,45 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
return -1;
}
+ g_psi.bsfc = av_bitstream_filter_init("h264_mp4toannexb");
+ printf("g_psi.bsfc %p\n", g_psi.bsfc);
+
+ if (xrdpvr_set_video_format(channel, 101))
+ {
+ printf("xrdpvr_set_video_format() failed\n");
+ return -1;
+ }
+
+ printf("xrdpvr_play_media: calling xrdpvr_set_audio_format\n");
+ if (xrdpvr_set_audio_format(channel, 101,
+ g_psi.p_audio_codec_ctx->extradata,
+ g_psi.p_audio_codec_ctx->extradata_size,
+ g_psi.p_audio_codec_ctx->sample_rate,
+ g_psi.p_audio_codec_ctx->bit_rate,
+ g_psi.p_audio_codec_ctx->channels,
+ g_psi.p_audio_codec_ctx->block_align))
+ {
+ printf("xrdpvr_set_audio_format() failed\n");
+ return 1;
+ }
+
return 0;
}
static int firstAudioPkt = 1;
static int firstVideoPkt = 1;
-int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
+/******************************************************************************/
+int
+xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
{
- AVPacket *av_pkt;
- double dts;
+ AVPacket *av_pkt;
+ double dts;
+ int error;
+ AVBitStreamFilterContext *bsfc;
+ AVPacket new_pkt;
+ //printf("xrdpvr_get_frame:\n");
/* alloc an AVPacket */
if ((av_pkt = (AVPacket *) malloc(sizeof(AVPacket))) == NULL)
return -1;
@@ -292,6 +377,34 @@ int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
}
else if (av_pkt->stream_index == g_video_index)
{
+
+ bsfc = g_psi.bsfc;
+ //printf("hi %p\n", bsfc);
+ while (bsfc != 0)
+ {
+ new_pkt = *av_pkt;
+ error = av_bitstream_filter_filter(bsfc, g_psi.p_video_codec_ctx, 0,
+ &new_pkt.data, &new_pkt.size,
+ av_pkt->data, av_pkt->size,
+ av_pkt->flags & AV_PKT_FLAG_KEY);
+ //printf("new size %d\n", new_pkt.size);
+ //hexdump(new_pkt.data, 32);
+ //printf("old size %d\n", av_pkt->size);
+ //hexdump(av_pkt->data, 32);
+ if (error > 0)
+ {
+ av_free_packet(av_pkt);
+ new_pkt.destruct = av_destruct_packet;
+ }
+ else if (error < 0)
+ {
+ printf("bitstream filter error\n");
+ }
+ *av_pkt = new_pkt;
+ bsfc = bsfc->next;
+ }
+
+
dts = av_pkt->dts;
//printf("$$$ video raw_dts=%f raw_pts=%f\n", (double) av_pkt->dts, (double) av_pkt->dts);
@@ -324,7 +437,9 @@ int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
return 0;
}
-int send_audio_pkt(void *channel, int stream_id, void *pkt_p)
+/******************************************************************************/
+int
+send_audio_pkt(void *channel, int stream_id, void *pkt_p)
{
AVPacket *av_pkt = (AVPacket *) pkt_p;
@@ -333,7 +448,9 @@ int send_audio_pkt(void *channel, int stream_id, void *pkt_p)
free(av_pkt);
}
-int send_video_pkt(void *channel, int stream_id, void *pkt_p)
+/******************************************************************************/
+int
+send_video_pkt(void *channel, int stream_id, void *pkt_p)
{
AVPacket *av_pkt = (AVPacket *) pkt_p;
@@ -342,11 +459,18 @@ int send_video_pkt(void *channel, int stream_id, void *pkt_p)
free(av_pkt);
}
-int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audioTimeout)
+/******************************************************************************/
+int
+xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audioTimeout)
{
- AVPacket av_pkt;
- double dts;
- int delay_in_us;
+ AVPacket av_pkt;
+ double dts;
+ int delay_in_us;
+ int error;
+ AVBitStreamFilterContext *bsfc;
+ AVPacket new_pkt;
+
+ //printf("xrdpvr_play_frame:\n");
if (av_read_frame(g_psi.p_format_ctx, &av_pkt) < 0)
{
@@ -375,12 +499,34 @@ int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audi
g_psi.audioTimeout = dts;
}
- //printf("audio delay: %d\n", delay_in_us);
+ printf("audio delay: %d\n", delay_in_us);
usleep(delay_in_us);
//usleep(1000 * 1);
}
else if (av_pkt.stream_index == g_video_index)
{
+ bsfc = g_psi.bsfc;
+ printf("hi %p\n", bsfc);
+ while (bsfc != 0)
+ {
+ new_pkt= av_pkt;
+ error = av_bitstream_filter_filter(bsfc, g_psi.p_video_codec_ctx, 0,
+ &new_pkt.data, &new_pkt.size,
+ av_pkt.data, av_pkt.size,
+ av_pkt.flags & AV_PKT_FLAG_KEY);
+ if (error > 0)
+ {
+ av_free_packet(&av_pkt);
+ new_pkt.destruct = av_destruct_packet;
+ }
+ else if (error < 0)
+ {
+ printf("bitstream filter error\n");
+ }
+ av_pkt = new_pkt;
+ bsfc = bsfc->next;
+ }
+
xrdpvr_send_video_data(channel, stream_id, av_pkt.size, av_pkt.data);
dts = av_pkt.dts;
@@ -404,7 +550,7 @@ int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audi
//printf("xrdpvr_play_frame:video2: saved=%f dts=%f delay_in_us=%d\n", g_psi.videoTimeout, dts, delay_in_us);
}
- //printf("video delay: %d\n", delay_in_us);
+ printf("video delay: %d\n", delay_in_us);
usleep(delay_in_us);
}
@@ -412,6 +558,7 @@ int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audi
return 0;
}
+/******************************************************************************/
int
xrdpvr_seek_media(int64_t pos, int backward)
{
@@ -439,6 +586,7 @@ xrdpvr_seek_media(int64_t pos, int backward)
return 0;
}
+/******************************************************************************/
void
xrdpvr_get_media_duration(int64_t *start_time, int64_t *duration)
{
@@ -446,6 +594,7 @@ xrdpvr_get_media_duration(int64_t *start_time, int64_t *duration)
*duration = g_psi.p_format_ctx->duration / AV_TIME_BASE;
}
+/******************************************************************************/
int
xrdpvr_set_geometry(void *channel, int stream_id, int xpos, int ypos, int width, int height)
{
@@ -454,7 +603,7 @@ xrdpvr_set_geometry(void *channel, int stream_id, int xpos, int ypos, int width,
int rv;
int len;
-printf("xrdpvr_set_geometry: entered; x=%d y=%d\n", xpos, ypos);
+ printf("xrdpvr_set_geometry: entered; x=%d y=%d\n", xpos, ypos);
stream_new(s, MAX_PDU_SIZE);
@@ -496,7 +645,6 @@ xrdpvr_set_video_format(void *channel, uint32_t stream_id)
int len;
stream_new(s, MAX_PDU_SIZE);
-
stream_ins_u32_le(s, 0); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_SET_VIDEO_FORMAT);
stream_ins_u32_le(s, stream_id);
@@ -523,7 +671,9 @@ xrdpvr_set_video_format(void *channel, uint32_t stream_id)
* @return 0 on success, -1 on error
*****************************************************************************/
int
-xrdpvr_set_audio_format(void *channel, uint32_t stream_id)
+xrdpvr_set_audio_format(void *channel, uint32_t stream_id, char *extradata,
+ int extradata_size, int sample_rate, int bit_rate,
+ int channels, int block_align)
{
STREAM *s;
char *cptr;
@@ -532,9 +682,20 @@ xrdpvr_set_audio_format(void *channel, uint32_t stream_id)
stream_new(s, MAX_PDU_SIZE);
+ printf("extradata_size %d sample_rate %d bit_rate %d channels %d "
+ "block_align %d\n", extradata_size, sample_rate, bit_rate,
+ channels, block_align);
+
stream_ins_u32_le(s, 0); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_SET_AUDIO_FORMAT);
stream_ins_u32_le(s, stream_id);
+ stream_ins_u32_le(s, extradata_size);
+ memcpy(s->p, extradata, extradata_size);
+ s->p += extradata_size;
+ stream_ins_u32_le(s, sample_rate);
+ stream_ins_u32_le(s, bit_rate);
+ stream_ins_u32_le(s, channels);
+ stream_ins_u32_le(s, block_align);
/* insert number of bytes in stream */
len = stream_length(s) - 4;
@@ -567,6 +728,7 @@ xrdpvr_send_video_data(void *channel, uint32_t stream_id, uint32_t data_len, uin
int rv;
int len;
+ //printf("xrdpvr_send_video_data:\n");
stream_new(s, MAX_PDU_SIZE + data_len);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
@@ -611,6 +773,7 @@ xrdpvr_send_audio_data(void *channel, uint32_t stream_id, uint32_t data_len, uin
int rv;
int len;
+ //printf("xrdpvr_send_audio_data:\n");
stream_new(s, MAX_PDU_SIZE + data_len);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
@@ -629,6 +792,7 @@ xrdpvr_send_audio_data(void *channel, uint32_t stream_id, uint32_t data_len, uin
/* write data to virtual channel */
rv = xrdpvr_write_to_client(channel, s);
stream_free(s);
+
return rv;
}
@@ -708,6 +872,33 @@ xrdpvr_create_metadata_file(void *channel, char *filename)
}
/**
+ ******************************************************************************/
+static int
+xrdpvr_read_from_client(void *channel, STREAM *s, int bytes, int timeout)
+{
+ unsigned int bytes_read;
+ int total_read;
+ int ok;
+
+ //printf("xrdpvr_read_from_client:\n");
+ total_read = 0;
+ while (total_read < bytes)
+ {
+ //printf("xrdpvr_read_from_client: loop\n");
+ bytes_read = bytes - total_read;
+ ok = WTSVirtualChannelRead(channel, timeout, s->p, bytes_read, &bytes_read);
+ //printf("xrdpvr_read_from_client: loop ok %d\n", ok);
+ if (ok)
+ {
+ //printf("xrdpvr_read_from_client: bytes_read %d\n", bytes_read);
+ total_read += bytes_read;
+ s->p += bytes_read;
+ }
+ }
+ return 0;
+}
+
+/**
* write data to a xrdpvr client
*
* @param channel opaque handle returned by WTSVirtualChannelOpenEx
@@ -785,3 +976,43 @@ xrdpvr_set_volume(void *channel, int volume)
stream_free(s);
return rv;
}
+
+int
+xrdpvr_send_init(void *channel)
+{
+ STREAM *s;
+ char *cptr;
+ int rv;
+ int len;
+
+ printf("xrdpvr_send_init:\n");
+ stream_new(s, MAX_BUFSIZE);
+
+ stream_ins_u32_le(s, 0); /* number of bytes to follow */
+ stream_ins_u32_le(s, CMD_INIT_XRDPVR);
+
+ /* insert number of bytes in stream */
+ len = stream_length(s) - 4;
+ cptr = s->p;
+ s->p = s->data;
+ stream_ins_u32_le(s, len);
+ s->p = cptr;
+
+ /* write data to virtual channel */
+ rv = xrdpvr_write_to_client(channel, s);
+ stream_free(s);
+ return rv;
+}
+
+int
+xrdpvr_read_ack(void *channel, int *frame)
+{
+ STREAM *s;
+
+ stream_new(s, MAX_PDU_SIZE);
+ xrdpvr_read_from_client(channel, s, 4, 1000);
+ s->p = s->data;
+ stream_ext_u32_le(s, *frame);
+ stream_free(s);
+ return 0;
+}
diff --git a/xrdpvr/xrdpvr.h b/xrdpvr/xrdpvr.h
index 1324282c..e6ab69e8 100644
--- a/xrdpvr/xrdpvr.h
+++ b/xrdpvr/xrdpvr.h
@@ -34,7 +34,9 @@ int xrdpvr_deinit_player(void *channel, int stream_id);
int xrdpvr_play_media(void *channel, int stream_id, char *filename);
int xrdpvr_set_geometry(void *channel, int stream_id, int xpos, int ypos, int width, int height);
int xrdpvr_set_video_format(void *channel, uint32_t stream_id);
-int xrdpvr_set_audio_format(void *channel, uint32_t stream_id);
+int xrdpvr_set_audio_format(void *channel, uint32_t stream_id, char *extradata,
+ int extradata_size, int sample_rate, int bit_rate,
+ int channels, int block_align);
int xrdpvr_send_video_data(void *channel, uint32_t stream_id, uint32_t data_len, uint8_t *data);
int xrdpvr_send_audio_data(void *channel, uint32_t stream_id, uint32_t data_len, uint8_t *data);
int xrdpvr_create_metadata_file(void *channel, char *filename);
@@ -45,6 +47,8 @@ int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us);
int send_audio_pkt(void *channel, int stream_id, void *pkt_p);
int send_video_pkt(void *channel, int stream_id, void *pkt_p);
int xrdpvr_set_volume(void *channel, int volume);
+int xrdpvr_send_init(void *channel);
+int xrdpvr_read_ack(void *channel, int *frame);
#ifdef __cplusplus
}
diff --git a/xrdpvr/xrdpvr_internal.h b/xrdpvr/xrdpvr_internal.h
index ca01941c..0b9ba6c8 100644
--- a/xrdpvr/xrdpvr_internal.h
+++ b/xrdpvr/xrdpvr_internal.h
@@ -62,6 +62,7 @@
#define CMD_DEINIT_XRDPVR 8
#define CMD_SET_GEOMETRY 9
#define CMD_SET_VOLUME 10
+#define CMD_INIT_XRDPVR 11
/* max number of bytes we can send in one pkt */
#define MAX_PDU_SIZE 1600
@@ -217,8 +218,11 @@ typedef struct _player_state_info
AVFrame *frame;
AVPacket avpkt;
+ AVBitStreamFilterContext *bsfc;
+
} PLAYER_STATE_INFO;
+static int xrdpvr_read_from_client(void *channel, STREAM *s, int bytes, int timeout);
static int xrdpvr_write_to_client(void *channel, STREAM *s);
#endif /* __XRDPVR_INTERNAL_H__ */