Идиоматический c способ получить длину свойства окна в X11? - PullRequest
0 голосов
/ 22 апреля 2020

Вчера я только начал изучать X11, и мне очень трудно найти информацию о нем.

Я бы хотел получить заголовок UTF-8 _NET_WM_NAME окна X11. Проблема в том, что вы должны вызывать его с параметром длины. Мое текущее решение состоит в том, чтобы сначала получить длину строки, используя XGetWindowProperty с параметром длины 0, а затем снова вызвать XGetWindowProperty, используя информацию bytes_after_return для length.

Проблема заключается в том, что включает в себя два распределения и освобождения. Я не очень продвинутый программист, но это, вероятно, не хорошо, верно? Хотя на практике два выделения для чего-то небольшого и нечастого, например, получения заголовка окна, вероятно, не будут иметь большого значения, я везде слышу, что все еще следует избегать ненужных выделений и освобождений.

Вот мой код:

Atom actualType;
int actualFormat;
unsigned long nItems;
unsigned long bytesAfter;
unsigned char* prop;

XGetWindowProperty(
    display, 
    window,
    _NET_WM_NAME,
    0UL,
    0UL,
    False,
    UTF8_STRING,
    &actualType,
    &actualFormat,
    &nItems,
    &bytesAfter,
    &prop
);

XFree(prop);

XGetWindowProperty(
    display, 
    window,
    _NET_WM_NAME,
    0UL,
    (bytesAfter + 3UL) / 4UL, // Divide by four and round up
    False,
    UTF8_STRING,
    &actualType,
    &actualFormat,
    &nItems,
    &bytesAfter,
    &prop
);

printf("title: %s", prop);

XFree(prop);

Есть ли лучший способ сделать это?

Альтернативным решением будет просто сохранить заголовок каждый раз, когда он установлен, но я не уверен, возможно ли это для сохраненный и фактический заголовок для десинхронизации.

Спасибо, чел <3 </p>

1 Ответ

1 голос
/ 22 апреля 2020

Нет ничего плохого в нескольких распределениях, если они неизбежны, и вам, вероятно, придется делать это в любом случае для больших объемов данных. Запросите разумное количество байтов и используйте al oop для обработки входящих данных по мере необходимости, используя параметр смещения, чтобы указать, где продолжить чтение. Если 4*length больше, чем объем возвращаемых данных, он вернет только необходимый объем данных, поэтому вам не нужно беспокоиться о расчете правильной длины с помощью параметра bytesAfter:

Atom actualType;
int actualFormat;
unsigned long nItems;
unsigned long bytesAfter;
unsigned char* prop;

// specify length as number of bytes divided by 4
#define MB (1048576)
long length = (64 * MB) / 4;

printf("title: ");
for (long offset = 0;; offset += length) {

    XGetWindowProperty(
        display,
        window,
        _NET_WM_NAME,
        offset,
        length,
        False,
        UTF8_STRING,
        &actualType,
        &actualFormat,
        &nItems,
        &bytesAfter,
        &prop
    );

    printf("%s", prop);
    XFree(prop);
    if (bytesAfter == 0)
        break;
}

Естественно, вы можете запросить больше данных, если будете sh, корректируя length на основе bytesAfter по мере необходимости, и это действительно более эффективно, так как требуется меньше циклов запроса / ответа, не говоря уже о распределении. Однако иногда слишком много данных для обработки, и поэтому вам, вероятно, все равно понадобится al oop. Это особенно верно, если вы используете XConvertSelection и вам нужно иметь дело со свойством INCR , так как это означает, что серверу дисплея нужно отправить много данных.

...