LINUX.ORG.RU

Подписка на сообщения в xlib

 


1

1

Zubok, скажи пожалуйста, зачем в xlib нужно руками сообщать на какие сообщения/события ты хочешь подписку? Почему просто не текут все подряд? Почему нельзя/не стоит просто сначала на все подряд подписаться?

★★

Потому что иксы - это сетевая прозрачность какбэ. Если все события будут течь вхолостую, то забьют канал. Экономно к каналам относились. К тому же, твой цикл чтения сообщений будет на все левые события реагировать, хотя и не обрабатывать, но каждый раз case проходить.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Ясно. Спасибо.

Просто столкнулся с ситуацией в своем фреймворке, что когда вызываешь функцию отмены кастомной подписки на нужное событие, то нужно еще смотреть а не подписан ли еще на 3-4 других, потому что маска одна и та же. Для Move\Resize например. Или FocusLost\Receive например. Удобно было бы сразу на все подписаться и не отписываться. Но раз для сети, то ок, придется мучиться с проверками.

Чтобы не быть голословным:

Отписываемся от события X, switch-case типа события:

    case SML_EVENT_POINTERENTER:
        warehouse.elem[window].data.win.eventsmask &= ~EnterWindowMask;
        break;
    case SML_EVENT_POINTERLEAVE:
        warehouse.elem[window].data.win.eventsmask &= ~LeaveWindowMask;
        break;
    case SML_EVENT_WINDOWSHOW:
        if ((!(warehouse.elem[window].data.win.events[SML_EVENT_WINDOWRESIZE ])) &&
            (!(warehouse.elem[window].data.win.events[SML_EVENT_WINDOWMOVE   ])) &&
            (!(warehouse.elem[window].data.win.events[SML_EVENT_WINDOWDESTROY])) &&
            (!(warehouse.elem[window].data.win.events[SML_EVENT_WINDOWHIDE   ])))
             warehouse.elem[window].data.win.eventsmask &= ~StructureNotifyMask;
        break;
    case SML_EVENT_WINDOWHIDE:
        if ((!(warehouse.elem[window].data.win.events[SML_EVENT_WINDOWRESIZE ])) &&
            (!(warehouse.elem[window].data.win.events[SML_EVENT_WINDOWMOVE   ])) &&
            (!(warehouse.elem[window].data.win.events[SML_EVENT_WINDOWDESTROY])) &&
            (!(warehouse.elem[window].data.win.events[SML_EVENT_WINDOWSHOW   ])))
             warehouse.elem[window].data.win.eventsmask &= ~StructureNotifyMask;
        break;

sambist ★★
() автор топика
Ответ на: комментарий от sambist

Удобно было бы сразу на все подписаться и не отписываться.

Я вот сейчас лезть не хочу, но можно в core protocol подписаться на все варианты. Просто все биты в маске установить. Вот XCB эти биты перечисляет:

  <enum name="EventMask">
    <item name="NoEvent">           <value>0</value></item>
    <item name="KeyPress">            <bit>0</bit></item>
    <item name="KeyRelease">          <bit>1</bit></item>
    <item name="ButtonPress">         <bit>2</bit></item>
    <item name="ButtonRelease">       <bit>3</bit></item>
    <item name="EnterWindow">         <bit>4</bit></item>
    <item name="LeaveWindow">         <bit>5</bit></item>
    <item name="PointerMotion">       <bit>6</bit></item>
    <item name="PointerMotionHint">   <bit>7</bit></item>
    <item name="Button1Motion">       <bit>8</bit></item>
    <item name="Button2Motion">       <bit>9</bit></item>
    <item name="Button3Motion">       <bit>10</bit></item>
    <item name="Button4Motion">       <bit>11</bit></item>
    <item name="Button5Motion">       <bit>12</bit></item>
    <item name="ButtonMotion">        <bit>13</bit></item>
    <item name="KeymapState">         <bit>14</bit></item>
    <item name="Exposure">            <bit>15</bit></item>
    <item name="VisibilityChange">    <bit>16</bit></item>
    <item name="StructureNotify">     <bit>17</bit></item>
    <item name="ResizeRedirect">      <bit>18</bit></item>
    <item name="SubstructureNotify">  <bit>19</bit></item>
    <item name="SubstructureRedirect"><bit>20</bit></item>
    <item name="FocusChange">         <bit>21</bit></item>
    <item name="PropertyChange">      <bit>22</bit></item>
    <item name="ColorMapChange">      <bit>23</bit></item>
    <item name="OwnerGrabButton">     <bit>24</bit></item>
  </enum>

То есть маска 0x1fff получается вроде. Но мне кажется, что это плохой стиль - лезть на низкий уровень. Лучще OR всем маскам из библиотеки xlib/xcb сделать и сделать составную маску.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от sambist
make_event_mask([], M) -> M;
make_event_mask([keyPress|T], M) -> make_event_mask(T, M bor 16#1);
make_event_mask([keyRelease|T], M) -> make_event_mask(T, M bor 16#2);
make_event_mask([buttonPress|T], M) -> make_event_mask(T, M bor 16#4);
make_event_mask([buttonRelease|T], M) -> make_event_mask(T, M bor 16#8);
make_event_mask([enterWindow|T], M) -> make_event_mask(T, M bor 16#10);
make_event_mask([leaveWindow|T], M) -> make_event_mask(T, M bor 16#20);
make_event_mask([pointerMotion|T], M) -> make_event_mask(T, M bor 16#40);
make_event_mask([pointerMotionHint|T], M) -> make_event_mask(T, M bor 16#80);
make_event_mask([button1Motion|T], M) -> make_event_mask(T, M bor 16#100);
make_event_mask([button2Motion|T], M) -> make_event_mask(T, M bor 16#200);
make_event_mask([button3Motion|T], M) -> make_event_mask(T, M bor 16#400);
make_event_mask([button4Motion|T], M) -> make_event_mask(T, M bor 16#800);
make_event_mask([button5Motion|T], M) -> make_event_mask(T, M bor 16#1000);
make_event_mask([buttonMotion|T], M) -> make_event_mask(T, M bor 16#2000);
make_event_mask([keymapState|T], M) -> make_event_mask(T, M bor 16#4000);
make_event_mask([exposure|T], M) -> make_event_mask(T, M bor 16#8000);
make_event_mask([visibilityChange|T], M) -> make_event_mask(T, M bor 16#10000);
make_event_mask([structureNotify|T], M) -> make_event_mask(T, M bor 16#20000);
make_event_mask([resizeRedirect|T], M) -> make_event_mask(T, M bor 16#40000);
make_event_mask([substructureNotify|T], M) -> make_event_mask(T, M bor 16#80000);
make_event_mask([substructureRedirect|T], M) -> make_event_mask(T, M bor 16#100000);
make_event_mask([focusChange|T], M) -> make_event_mask(T, M bor 16#200000);
make_event_mask([propertyChange|T], M) -> make_event_mask(T, M bor 16#400000);
make_event_mask([colormapChange|T], M) -> make_event_mask(T, M bor 16#800000);
make_event_mask([ownerGrabButton|T], M) -> make_event_mask(T, M bor 16#1000000).

x windows system protocol, application B, Common Types, SETofEVENT

anonymous
()
Ответ на: комментарий от Zubok

То есть маска 0x1fff получается вроде.

У меня там еще меньше, я не все события использую. Например ColorMapChange мне даром не нужен ну и т.д.

Но мне кажется, что это плохой стиль - лезть на низкий уровень.

В смысле? У меня и так все ниже некуда. Разве что писать замену иксам :D

sambist ★★
() автор топика
Ответ на: комментарий от anonymous

Да не, какое событие на какую маску подписывать я знаю, просто ладно бы для каждого события своя маска была, так нет, неравномерно распределено.

sambist ★★
() автор топика
Ответ на: комментарий от sambist

В смысле? У меня и так все ниже некуда. Разве что писать замену иксам :D

Я имел в виду числовые значения масок использовать напрямую, а не именованные константы. Совсем не то, что ты xlib напрямую используешь. Кстати, чуть-чуть ниже уровень - это XCB. Совсем чуть-чуть. А еще ниже - это уже писать свою библиотеку xlib/xcb. Я один раз попробовал. :)

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Я имел в виду числовые значения масок использовать напрямую

Ааа. Не, я таким геморроем не занимаюсь, пусть у компилятора голова болит.

sambist ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.