VirtualBox

Changeset 82889 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jan 28, 2020 3:48:36 PM (5 years ago)
Author:
vboxsync
Message:

Shared Clipboard: Generate separate messages in ShClSvcDataReadRequest() when requesting multiple clipboard formats at once. This should fix Darwin clipboard handling. bugref:9437

Location:
trunk/src/VBox/HostServices/SharedClipboard
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h

    r82880 r82889  
    241241 * @{
    242242 */
    243 int ShClSvcDataReadRequest(PSHCLCLIENT pClient, SHCLFORMAT fFormat, PSHCLEVENTID pidEvent);
     243int ShClSvcDataReadRequest(PSHCLCLIENT pClient, SHCLFORMATS fFormats, PSHCLEVENTID pidEvent);
    244244int ShClSvcDataReadSignal(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData);
    245245int ShClSvcHostReportFormats(PSHCLCLIENT pClient, SHCLFORMATS fFormats);
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r82880 r82889  
    11901190 * @returns VBox status code.
    11911191 * @param   pClient             Client to request to read data form.
    1192  * @param   fFormat             The format being requested (VBOX_SHCL_FMT_XXX).
     1192 * @param   fFormats            The formats being requested, OR'ed together (VBOX_SHCL_FMT_XXX).
    11931193 * @param   pidEvent            Event ID for waiting for new data. Optional.
    11941194 */
    1195 int ShClSvcDataReadRequest(PSHCLCLIENT pClient, SHCLFORMAT fFormat, PSHCLEVENTID pidEvent)
     1195int ShClSvcDataReadRequest(PSHCLCLIENT pClient, SHCLFORMATS fFormats, PSHCLEVENTID pidEvent)
    11961196{
    11971197    LogFlowFuncEnter();
    11981198    if (pidEvent)
    1199         *pidEvent = 0;
     1199        *pidEvent = NIL_SHCLEVENTID;
    12001200    AssertPtrReturn(pClient,  VERR_INVALID_POINTER);
    12011201
    1202     /*
    1203      * Allocate a message.
    1204      */
    1205     int rc;
    1206     PSHCLCLIENTMSG pMsg = shClSvcMsgAlloc(pClient,
    1207                                           pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID
    1208                                           ? VBOX_SHCL_HOST_MSG_READ_DATA_CID : VBOX_SHCL_HOST_MSG_READ_DATA,
    1209                                           2);
    1210     if (pMsg)
    1211     {
     1202    LogFlowFunc(("fFormats=%#x\n", fFormats));
     1203
     1204    int rc = VERR_NOT_SUPPORTED;
     1205
     1206    while (fFormats)
     1207    {
     1208        SHCLFORMAT fFormat = VBOX_SHCL_FMT_NONE;
     1209
     1210        /** @todo Make format reporting precedence configurable? */
     1211        if (fFormats & VBOX_SHCL_FMT_UNICODETEXT)
     1212            fFormat = VBOX_SHCL_FMT_UNICODETEXT;
     1213        else if (fFormats & VBOX_SHCL_FMT_BITMAP)
     1214            fFormat = VBOX_SHCL_FMT_BITMAP;
     1215        else if (fFormats & VBOX_SHCL_FMT_HTML)
     1216            fFormat = VBOX_SHCL_FMT_HTML;
     1217        else
     1218            AssertStmt(fFormats == VBOX_SHCL_FMT_NONE, fFormat = VBOX_SHCL_FMT_NONE);
     1219
     1220        if (fFormat == VBOX_SHCL_FMT_NONE)
     1221            break;
     1222
     1223        /* Remove format from format list. */
     1224        fFormats &= ~fFormat;
     1225
    12121226        /*
    1213          * Enter the critical section and generate an event.
     1227         * Allocate messages, one for each format.
    12141228         */
     1229        PSHCLCLIENTMSG pMsg = shClSvcMsgAlloc(pClient,
     1230                                              pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID
     1231                                              ? VBOX_SHCL_HOST_MSG_READ_DATA_CID : VBOX_SHCL_HOST_MSG_READ_DATA,
     1232                                              2);
     1233        if (pMsg)
     1234        {
     1235            /*
     1236             * Enter the critical section and generate an event.
     1237             */
     1238            RTCritSectEnter(&pClient->CritSect);
     1239
     1240            const SHCLEVENTID idEvent = ShClEventIdGenerateAndRegister(&pClient->EventSrc);
     1241            if (idEvent != NIL_SHCLEVENTID)
     1242            {
     1243                LogFlowFunc(("fFormats=%#x -> fFormat=%#x, idEvent=%#x\n", fFormats, fFormat, idEvent));
     1244
     1245                /*
     1246                 * Format the message.
     1247                 */
     1248                if (pMsg->idMsg == VBOX_SHCL_HOST_MSG_READ_DATA_CID)
     1249                    HGCMSvcSetU64(&pMsg->aParms[0],
     1250                                  VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID, pClient->EventSrc.uID, idEvent));
     1251                else
     1252                    HGCMSvcSetU32(&pMsg->aParms[0], VBOX_SHCL_HOST_MSG_READ_DATA);
     1253                HGCMSvcSetU32(&pMsg->aParms[1], fFormat);
     1254
     1255                shClSvcMsgAdd(pClient, pMsg, true /* fAppend */);
     1256
     1257                rc = VINF_SUCCESS;
     1258            }
     1259            else
     1260                rc = VERR_SHCLPB_MAX_EVENTS_REACHED;
     1261
     1262            RTCritSectLeave(&pClient->CritSect);
     1263        }
     1264        else
     1265            rc = VERR_NO_MEMORY;
     1266
     1267        if (RT_FAILURE(rc))
     1268            break;
     1269    }
     1270
     1271    if (RT_SUCCESS(rc))
     1272    {
    12151273        RTCritSectEnter(&pClient->CritSect);
    12161274
    1217         const SHCLEVENTID idEvent = ShClEventIdGenerateAndRegister(&pClient->EventSrc);
    1218         if (idEvent != NIL_SHCLEVENTID)
    1219         {
    1220             LogFlowFunc(("fFormat=%#x idEvent=%#x\n", fFormat, idEvent));
    1221 
    1222             /*
    1223              * Format the message
    1224              */
    1225             if (pMsg->idMsg == VBOX_SHCL_HOST_MSG_READ_DATA_CID)
    1226                 HGCMSvcSetU64(&pMsg->aParms[0], VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID, pClient->EventSrc.uID, idEvent));
    1227             else
    1228                 HGCMSvcSetU32(&pMsg->aParms[0], VBOX_SHCL_HOST_MSG_READ_DATA);
    1229             HGCMSvcSetU32(&pMsg->aParms[1], fFormat);
    1230 
    1231             /*
    1232              * Queue it and wake up the client if it's waiting on a message.
    1233              */
    1234             shClSvcMsgAddAndWakeupClient(pClient, pMsg);
    1235             if (pidEvent)
    1236                 *pidEvent = idEvent;
    1237             rc = VINF_SUCCESS;
    1238         }
    1239         else
    1240             rc = VERR_SHCLPB_MAX_EVENTS_REACHED;
     1275        shClSvcClientWakeup(pClient);
    12411276
    12421277        RTCritSectLeave(&pClient->CritSect);
    12431278    }
    1244     else
    1245         rc = VERR_NO_MEMORY;
     1279
     1280    /** @todo BUGBUG What to do with allocated events? Which one to return? */
    12461281
    12471282    LogFlowFuncLeaveRC(rc);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette