File indexing completed on 2024-05-19 16:34:57

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2022 MBition GmbH
0006     SPDX-FileContributor: Kai Uwe Broulik <kai_uwe.broulik@mbition.io>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #pragma once
0012 
0013 #include <config-kwin.h>
0014 #include <kwin_export.h>
0015 
0016 #if HAVE_MEMFD
0017 #include "filedescriptor.h"
0018 #else
0019 #include <QTemporaryFile>
0020 #include <memory>
0021 #endif
0022 
0023 #include <QFlag>
0024 
0025 class QByteArray;
0026 
0027 namespace KWin
0028 {
0029 
0030 /**
0031  * @brief Creates a file in memory.
0032  *
0033  * This is useful for passing larger data to clients,
0034  * for example the xkeymap.
0035  *
0036  * If memfd is supported, it is used, otherwise
0037  * a temporary file is created.
0038  *
0039  * @note It is advisable not to send the same file
0040  * descriptor out to multiple clients unless it
0041  * is sealed for writing. Check which flags actually
0042  * apply before handing out the file descriptor.
0043  *
0044  * @sa effectiveFlags()
0045  */
0046 class KWIN_EXPORT RamFile
0047 {
0048 public:
0049     /**
0050      * Flags to use when creating the file.
0051      *
0052      * @note Check with effectiveFlags() which flags
0053      * actually apply after the file was created.
0054      */
0055     enum class Flag {
0056         SealWrite = 1 << 0, ///< Seal the file descriptor for writing.
0057     };
0058     Q_DECLARE_FLAGS(Flags, Flag)
0059 
0060     RamFile() = default;
0061     /**
0062      * Create a file of given size with given data.
0063      *
0064      * @note You should call seal() after copying the data into the file.
0065      *
0066      * @param name The file name, useful for debugging.
0067      * @param data The data to store in the file.
0068      * @param size The size of the file.
0069      * @param flags The flags to use when creating the file.
0070      */
0071     RamFile(const char *name, const void *inData, int size, Flags flags = {});
0072 
0073     RamFile(RamFile &&other) Q_DECL_NOEXCEPT;
0074     RamFile &operator=(RamFile &&other) Q_DECL_NOEXCEPT;
0075 
0076     /**
0077      * Destroys the file.
0078      */
0079     ~RamFile();
0080 
0081     /**
0082      * Whether this instance contains a valid file descriptor.
0083      */
0084     bool isValid() const;
0085     /**
0086      * The flags that are effectively applied.
0087      *
0088      * For instance, even though SealWrite was passed in the constructor,
0089      * it might not be supported.
0090      */
0091     Flags effectiveFlags() const;
0092 
0093     /**
0094      * The underlying file descriptor
0095      *
0096      * @return The fd, or -1 if there is none.
0097      */
0098     int fd() const;
0099     /**
0100      * The size of the file
0101      */
0102     int size() const;
0103 
0104 private:
0105     void cleanup();
0106 
0107     int m_size = 0;
0108     Flags m_flags = {};
0109 
0110 #if HAVE_MEMFD
0111     KWin::FileDescriptor m_fd;
0112 #else
0113     std::unique_ptr<QTemporaryFile> m_tmp;
0114 #endif
0115 };
0116 
0117 } // namespace KWin