mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Allow groupchat creation
This commit is contained in:
parent
beaebc2056
commit
a2566d4183
88
core.cpp
88
core.cpp
|
@ -893,9 +893,18 @@ void Core::onAvStart(int32_t call_index, void* core)
|
||||||
qWarning() << "Core: Received invalid AV start";
|
qWarning() << "Core: Received invalid AV start";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << QString("Core: AV start from %1").arg(friendId);
|
|
||||||
|
|
||||||
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav);
|
int transType = toxav_get_peer_transmission_type(static_cast<Core*>(core)->toxav, call_index, friendId);
|
||||||
|
if (transType == TypeVideo)
|
||||||
|
{
|
||||||
|
qDebug() << QString("Core: AV start from %1 with video").arg(friendId);
|
||||||
|
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << QString("Core: AV start from %1 without video").arg(friendId);
|
||||||
|
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav, false);
|
||||||
|
}
|
||||||
|
|
||||||
emit static_cast<Core*>(core)->avStart(friendId, call_index);
|
emit static_cast<Core*>(core)->avStart(friendId, call_index);
|
||||||
}
|
}
|
||||||
|
@ -954,9 +963,17 @@ void Core::onAvStarting(int32_t call_index, void* core)
|
||||||
qWarning() << "Core: Received invalid AV starting";
|
qWarning() << "Core: Received invalid AV starting";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << QString("Core: AV starting %1").arg(friendId);
|
int transType = toxav_get_peer_transmission_type(static_cast<Core*>(core)->toxav, call_index, friendId);
|
||||||
|
if (transType == TypeVideo)
|
||||||
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav);
|
{
|
||||||
|
qDebug() << QString("Core: AV starting from %1 with video").arg(friendId);
|
||||||
|
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << QString("Core: AV starting from %1 without video").arg(friendId);
|
||||||
|
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav, false);
|
||||||
|
}
|
||||||
|
|
||||||
emit static_cast<Core*>(core)->avStarting(friendId, call_index);
|
emit static_cast<Core*>(core)->avStarting(friendId, call_index);
|
||||||
}
|
}
|
||||||
|
@ -1009,9 +1026,24 @@ void Core::onAvPeerTimeout(int32_t call_index, void* core)
|
||||||
|
|
||||||
void Core::answerCall(int callId)
|
void Core::answerCall(int callId)
|
||||||
{
|
{
|
||||||
qDebug() << QString("Core: answering call %1").arg(callId);
|
int friendId = toxav_get_peer_id(toxav, callId, 0);
|
||||||
|
if (friendId < 0)
|
||||||
|
{
|
||||||
|
qWarning() << "Core: Received invalid AV answer peer ID";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int transType = toxav_get_peer_transmission_type(toxav, callId, friendId);
|
||||||
|
if (transType == TypeVideo)
|
||||||
|
{
|
||||||
|
qDebug() << QString("Core: answering call %1 with video").arg(callId);
|
||||||
|
toxav_answer(toxav, callId, TypeVideo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << QString("Core: answering call %1 without video").arg(callId);
|
||||||
toxav_answer(toxav, callId, TypeAudio);
|
toxav_answer(toxav, callId, TypeAudio);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Core::hangupCall(int callId)
|
void Core::hangupCall(int callId)
|
||||||
{
|
{
|
||||||
|
@ -1020,10 +1052,13 @@ void Core::hangupCall(int callId)
|
||||||
toxav_hangup(toxav, callId);
|
toxav_hangup(toxav, callId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::startCall(int friendId)
|
void Core::startCall(int friendId, bool video)
|
||||||
{
|
{
|
||||||
qDebug() << QString("Core: Starting call with %1").arg(friendId);
|
qDebug() << QString("Core: Starting call with %1").arg(friendId);
|
||||||
int callId;
|
int callId;
|
||||||
|
if (video)
|
||||||
|
toxav_call(toxav, &callId, friendId, TypeVideo, TOXAV_RINGING_TIME);
|
||||||
|
else
|
||||||
toxav_call(toxav, &callId, friendId, TypeAudio, TOXAV_RINGING_TIME);
|
toxav_call(toxav, &callId, friendId, TypeAudio, TOXAV_RINGING_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,13 +1069,14 @@ void Core::cancelCall(int callId, int friendId)
|
||||||
toxav_cancel(toxav, callId, friendId, 0);
|
toxav_cancel(toxav, callId, friendId, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::prepareCall(int friendId, int callId, ToxAv* toxav)
|
void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled)
|
||||||
{
|
{
|
||||||
qDebug() << QString("Core: preparing call %1").arg(callId);
|
qDebug() << QString("Core: preparing call %1").arg(callId);
|
||||||
calls[callId].callId = callId;
|
calls[callId].callId = callId;
|
||||||
calls[callId].friendId = friendId;
|
calls[callId].friendId = friendId;
|
||||||
calls[callId].codecSettings = av_DefaultSettings;
|
calls[callId].codecSettings = av_DefaultSettings;
|
||||||
toxav_prepare_transmission(toxav, callId, &calls[callId].codecSettings, false);
|
calls[callId].videoEnabled = videoEnabled;
|
||||||
|
toxav_prepare_transmission(toxav, callId, &calls[callId].codecSettings, videoEnabled);
|
||||||
|
|
||||||
// Prepare output
|
// Prepare output
|
||||||
QAudioFormat format;
|
QAudioFormat format;
|
||||||
|
@ -1079,6 +1115,7 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go
|
// Go
|
||||||
|
/// BUG: TODO: Memory corryption and crashes atexit when playCallAudio is threaded
|
||||||
if (calls[callId].audioOutput != nullptr)
|
if (calls[callId].audioOutput != nullptr)
|
||||||
calls[callId].playFuture = QtConcurrent::run(playCallAudio, callId, toxav);
|
calls[callId].playFuture = QtConcurrent::run(playCallAudio, callId, toxav);
|
||||||
if (calls[callId].audioInput != nullptr)
|
if (calls[callId].audioInput != nullptr)
|
||||||
|
@ -1119,8 +1156,7 @@ void Core::playCallAudio(int callId, ToxAv* toxav)
|
||||||
}
|
}
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
qApp->processEvents();
|
QThread::msleep(5); /// BUG: Another thread crashed with corruption while we slept here
|
||||||
QThread::msleep(5);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//qDebug() << QString("Core: Received %1 bytes, %2 audio bytes free, %3 core buffer size")
|
//qDebug() << QString("Core: Received %1 bytes, %2 audio bytes free, %3 core buffer size")
|
||||||
|
@ -1171,7 +1207,37 @@ void Core::sendCallAudio(int callId, ToxAv* toxav)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::sendVideoFrame(int callId, ToxAv* toxav, vpx_image img)
|
||||||
|
{
|
||||||
|
uint8_t videobuf[TOXAV_VIDEO_WIDTH * TOXAV_VIDEO_HEIGHT * 4];
|
||||||
|
int result;
|
||||||
|
if((result = toxav_prepare_video_frame(toxav, callId, videobuf, sizeof(videobuf), &img)) < 0)
|
||||||
|
{
|
||||||
|
qDebug() << QString("Core: Error preparing video frame: %1").arg(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((result = toxav_send_video(toxav, callId, videobuf, result)) < 0)
|
||||||
|
qDebug() << QString("Core: Error sending video frame: %1").arg(result);
|
||||||
|
}
|
||||||
|
|
||||||
void Core::groupInviteFriend(int friendId, int groupId)
|
void Core::groupInviteFriend(int friendId, int groupId)
|
||||||
{
|
{
|
||||||
tox_invite_friend(tox, friendId, groupId);
|
tox_invite_friend(tox, friendId, groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::createGroup()
|
||||||
|
{
|
||||||
|
emit emptyGroupCreated(tox_add_groupchat(tox));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::dispatchVideoFrame(vpx_image img) const
|
||||||
|
{
|
||||||
|
for (int i=0; i<TOXAV_MAX_CALLS; i++)
|
||||||
|
{
|
||||||
|
if (calls[i].active && calls[i].videoEnabled)
|
||||||
|
{
|
||||||
|
sendVideoFrame(i, toxav, img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
15
core.h
15
core.h
|
@ -42,6 +42,10 @@
|
||||||
#define TOX_BOOTSTRAP_INTERVAL 10*1000
|
#define TOX_BOOTSTRAP_INTERVAL 10*1000
|
||||||
#define TOXAV_RINGING_TIME 15
|
#define TOXAV_RINGING_TIME 15
|
||||||
|
|
||||||
|
// TODO: Put that in the settings
|
||||||
|
#define TOXAV_VIDEO_WIDTH 640
|
||||||
|
#define TOXAV_VIDEO_HEIGHT 480
|
||||||
|
|
||||||
struct DhtServer
|
struct DhtServer
|
||||||
{
|
{
|
||||||
QString name;
|
QString name;
|
||||||
|
@ -91,9 +95,10 @@ public:
|
||||||
ToxAvCodecSettings codecSettings;
|
ToxAvCodecSettings codecSettings;
|
||||||
int callId;
|
int callId;
|
||||||
int friendId;
|
int friendId;
|
||||||
bool active;
|
bool videoEnabled;
|
||||||
QFuture<void> playFuture;
|
QFuture<void> playFuture;
|
||||||
QFuture<void> recordFuture;
|
QFuture<void> recordFuture;
|
||||||
|
bool active;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Core : public QObject
|
class Core : public QObject
|
||||||
|
@ -108,6 +113,7 @@ public:
|
||||||
QList<QString> getGroupPeerNames(int groupId) const;
|
QList<QString> getGroupPeerNames(int groupId) const;
|
||||||
int joinGroupchat(int32_t friendnumber, uint8_t* friend_group_public_key) const;
|
int joinGroupchat(int32_t friendnumber, uint8_t* friend_group_public_key) const;
|
||||||
void quitGroupChat(int groupId) const;
|
void quitGroupChat(int groupId) const;
|
||||||
|
void dispatchVideoFrame(vpx_image img) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void start();
|
void start();
|
||||||
|
@ -117,6 +123,7 @@ public slots:
|
||||||
void acceptFriendRequest(const QString& userId);
|
void acceptFriendRequest(const QString& userId);
|
||||||
void requestFriendship(const QString& friendAddress, const QString& message);
|
void requestFriendship(const QString& friendAddress, const QString& message);
|
||||||
void groupInviteFriend(int friendId, int groupId);
|
void groupInviteFriend(int friendId, int groupId);
|
||||||
|
void createGroup();
|
||||||
|
|
||||||
void removeFriend(int friendId);
|
void removeFriend(int friendId);
|
||||||
void removeGroup(int groupId);
|
void removeGroup(int groupId);
|
||||||
|
@ -140,7 +147,7 @@ public slots:
|
||||||
|
|
||||||
void answerCall(int callId);
|
void answerCall(int callId);
|
||||||
void hangupCall(int callId);
|
void hangupCall(int callId);
|
||||||
void startCall(int friendId);
|
void startCall(int friendId, bool video=false);
|
||||||
void cancelCall(int callId, int friendId);
|
void cancelCall(int callId, int friendId);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -166,6 +173,7 @@ signals:
|
||||||
|
|
||||||
void friendLastSeenChanged(int friendId, const QDateTime& dateTime);
|
void friendLastSeenChanged(int friendId, const QDateTime& dateTime);
|
||||||
|
|
||||||
|
void emptyGroupCreated(int groupnumber);
|
||||||
void groupInviteReceived(int friendnumber, uint8_t *group_public_key);
|
void groupInviteReceived(int friendnumber, uint8_t *group_public_key);
|
||||||
void groupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message);
|
void groupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message);
|
||||||
void groupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
|
void groupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
|
||||||
|
@ -236,10 +244,11 @@ private:
|
||||||
static void onAvRequestTimeout(int32_t call_index, void* toxav);
|
static void onAvRequestTimeout(int32_t call_index, void* toxav);
|
||||||
static void onAvPeerTimeout(int32_t call_index, void* toxav);
|
static void onAvPeerTimeout(int32_t call_index, void* toxav);
|
||||||
|
|
||||||
static void prepareCall(int friendId, int callId, ToxAv *toxav);
|
static void prepareCall(int friendId, int callId, ToxAv *toxav, bool videoEnabled);
|
||||||
static void cleanupCall(int callId);
|
static void cleanupCall(int callId);
|
||||||
static void playCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread
|
static void playCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread
|
||||||
static void sendCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread
|
static void sendCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread
|
||||||
|
static void sendVideoFrame(int callId, ToxAv* toxav, vpx_image img);
|
||||||
|
|
||||||
void checkConnection();
|
void checkConnection();
|
||||||
void onBootstrapTimer();
|
void onBootstrapTimer();
|
||||||
|
|
|
@ -34,6 +34,9 @@ Widget::Widget(QWidget *parent) :
|
||||||
ui->statusLabel->setText(Settings::getInstance().getStatusMessage());
|
ui->statusLabel->setText(Settings::getInstance().getStatusMessage());
|
||||||
ui->friendList->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
ui->friendList->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
camera = new Camera;
|
||||||
|
camview = new SelfCamView(camera);
|
||||||
|
|
||||||
qRegisterMetaType<Status>("Status");
|
qRegisterMetaType<Status>("Status");
|
||||||
qRegisterMetaType<uint8_t>("uint8_t");
|
qRegisterMetaType<uint8_t>("uint8_t");
|
||||||
qRegisterMetaType<int32_t>("int32_t");
|
qRegisterMetaType<int32_t>("int32_t");
|
||||||
|
@ -65,6 +68,7 @@ Widget::Widget(QWidget *parent) :
|
||||||
connect(core, &Core::groupInviteReceived, this, &Widget::onGroupInviteReceived);
|
connect(core, &Core::groupInviteReceived, this, &Widget::onGroupInviteReceived);
|
||||||
connect(core, &Core::groupMessageReceived, this, &Widget::onGroupMessageReceived);
|
connect(core, &Core::groupMessageReceived, this, &Widget::onGroupMessageReceived);
|
||||||
connect(core, &Core::groupNamelistChanged, this, &Widget::onGroupNamelistChanged);
|
connect(core, &Core::groupNamelistChanged, this, &Widget::onGroupNamelistChanged);
|
||||||
|
connect(core, &Core::emptyGroupCreated, this, &Widget::onEmptyGroupCreated);
|
||||||
|
|
||||||
connect(this, &Widget::statusSet, core, &Core::setStatus);
|
connect(this, &Widget::statusSet, core, &Core::setStatus);
|
||||||
connect(this, &Widget::friendRequested, core, &Core::requestFriendship);
|
connect(this, &Widget::friendRequested, core, &Core::requestFriendship);
|
||||||
|
@ -93,6 +97,7 @@ Widget::~Widget()
|
||||||
coreThread->exit();
|
coreThread->exit();
|
||||||
coreThread->wait();
|
coreThread->wait();
|
||||||
delete core;
|
delete core;
|
||||||
|
delete camview;
|
||||||
|
|
||||||
hideMainForms();
|
hideMainForms();
|
||||||
|
|
||||||
|
@ -155,7 +160,7 @@ void Widget::onAddClicked()
|
||||||
|
|
||||||
void Widget::onGroupClicked()
|
void Widget::onGroupClicked()
|
||||||
{
|
{
|
||||||
|
core->createGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::onTransferClicked()
|
void Widget::onTransferClicked()
|
||||||
|
@ -521,3 +526,13 @@ Group *Widget::createGroup(int groupId)
|
||||||
connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString)));
|
connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString)));
|
||||||
return newgroup;
|
return newgroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::showTestCamview()
|
||||||
|
{
|
||||||
|
camview->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::onEmptyGroupCreated(int groupId)
|
||||||
|
{
|
||||||
|
createGroup(groupId);
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "widget/form/addfriendform.h"
|
#include "widget/form/addfriendform.h"
|
||||||
#include "widget/form/settingsform.h"
|
#include "widget/form/settingsform.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class Widget;
|
class Widget;
|
||||||
|
@ -27,6 +28,7 @@ public:
|
||||||
QString getUsername();
|
QString getUsername();
|
||||||
Core* getCore();
|
Core* getCore();
|
||||||
static Widget* getInstance();
|
static Widget* getInstance();
|
||||||
|
void showTestCamview();
|
||||||
~Widget();
|
~Widget();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -62,6 +64,7 @@ private slots:
|
||||||
void onFriendWidgetClicked(FriendWidget* widget);
|
void onFriendWidgetClicked(FriendWidget* widget);
|
||||||
void onFriendMessageReceived(int friendId, const QString& message);
|
void onFriendMessageReceived(int friendId, const QString& message);
|
||||||
void onFriendRequestReceived(const QString& userId, const QString& message);
|
void onFriendRequestReceived(const QString& userId, const QString& message);
|
||||||
|
void onEmptyGroupCreated(int groupId);
|
||||||
void onGroupInviteReceived(int32_t friendId, uint8_t *publicKey);
|
void onGroupInviteReceived(int32_t friendId, uint8_t *publicKey);
|
||||||
void onGroupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message);
|
void onGroupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message);
|
||||||
void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
|
void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
|
||||||
|
@ -72,6 +75,8 @@ private slots:
|
||||||
private:
|
private:
|
||||||
void hideMainForms();
|
void hideMainForms();
|
||||||
Group* createGroup(int groupId);
|
Group* createGroup(int groupId);
|
||||||
|
void newMessageAlert();
|
||||||
|
void updateFriendStatusLights(int friendId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::Widget *ui;
|
Ui::Widget *ui;
|
||||||
|
@ -82,9 +87,9 @@ private:
|
||||||
static Widget* instance;
|
static Widget* instance;
|
||||||
FriendWidget* activeFriendWidget;
|
FriendWidget* activeFriendWidget;
|
||||||
GroupWidget* activeGroupWidget;
|
GroupWidget* activeGroupWidget;
|
||||||
void updateFriendStatusLights(int friendId);
|
|
||||||
int isFriendWidgetActive, isGroupWidgetActive;
|
int isFriendWidgetActive, isGroupWidgetActive;
|
||||||
void newMessageAlert();
|
SelfCamView* camview;
|
||||||
|
Camera* camera;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WIDGET_H
|
#endif // WIDGET_H
|
||||||
|
|
Loading…
Reference in New Issue
Block a user