پروتکل اصلی سیستم پنجره‌بندی اکس

از ویکی‌پدیا، دانشنامهٔ آزاد
پرش به: ناوبری، جستجو
لوگوی سیستم پنجره اکس

پروتکل اصلی سیستم پنجره‌بندی اکس[۱][۲][۳] (به انگلیسی: X Window System core protocol) اساسی‌ترین پروتکل در ساختار سیستم پنجره‌بندی اکس است. سیستم پنجره‌بندی اکس یک سیستم پنجره‌بندی تحت شبکه برای نمایشگرهای بیت‌مپی است که برای بوجود آوردن واسط‌های گرافیکی کاربر در سیستم‌عامل‌های، یونیکس، شبه یونیکس و یا دیگر سیستم‌ها استفاده می‌شود. سیستم پنجره‌بندی اکس از یک مدل مشتری-خدمت‌گذار برخوردار است. در این مدل، یک سرویس‌دهنده واحد که سرور اکس نامیده می‌شود، تمامی سخت‌افزارهای ورودی/خروجی مانند صفحه نمایش، صفحه کلید، ماوس و ... را کنترل می‌کند. تمامی برنامه‌های کاربردی هم به صورت سرویس‌گیرنده عمل می‌کنند و از طریق سرور با کاربر یا دیگر کلاینت‌ها تعامل برقرار می‌کنند. این تعامل توسط پروتکل اصلی سیستم پنجره‌بندی اکس تنظیم می‌شود. پروتکل‌های دیگری هم در رابطه با سیستم پنجره‌بندی اکس وجود دارد، این پروتکل‌ها، هم به صورت یک پروتکل مجزا و مستقل هستند و هم اینکه بر روی بستر پروتکل اصلی اکس ایجاد شده‌اند.

در پروتکل اصلی سیستم پنجره‌بندی اکس، تنها چهار نوع بسته و به شکل ناهمگام،[و ۱] بر روی شبکه ارسال می‌شود: درخواست‌ها،[و ۲] پاسخ‌ها،[و ۳] رویدادها[و ۴] و خطاها.[و ۵] درخواست‌ها از طرف کلاینت به سرور فرستاده می‌شوند تا اجرای یک عملیات یا دریافت اطلاعاتی را از سرور درخواست کنند. درخواست‌ها یا به سرور می‌گویند که عملیات خاصی را انجام دهد (برای مثال، ایجاد کردن یک پنجره جدید) و یا از سرور می‌خواهند که داده‌های خاصی را در اختیار کلاینت‌ها قرار دهد. پاسخ‌ها از طرف سرور برای کلاینت‌ها ارسال می‌شوند و حاوی داده‌های درخواستی کلاینت هستند که در پاسخ به درخواست کلاینت‌ها در اختیار آنها قرار می‌گیرند. رویدادها توسط سرور به کلاینت ارسال می‌شوند و آنها کلاینت را از اعمالی که کاربر در حال انجام آنهاست و یا رخدادهای دیگری که ممکن است کلاینت علاقه‌مند به دانستن آنها باشد، با خبر می‌کنند و کلاینت می‌تواند واکنش مناسب به رویدادها را نشان دهد. هنگامی که اتفاق غیر منتظره‌ای در هنگام پردازش کردن درخواست‌های کلاینت رخ می‌دهد و خطایی اتفاق می‌افتد، سرور این خطاها را به کمک بسته‌هایی از نوع خطا به اطلاع کلاینت می‌رساند. درخواست‌ها ممکن است باعث تولید کردن پاسخ‌ها، رویدادها یا خطاها شوند؛ علاوه بر آن، سرور اجبار نمی‌کند که بسته‌ها حتماً باید به ترتیب خاصی بر روی شبکه ارسال شوند. چندین افزونه برای پروتکل اصلی وجود دارد که هر کدام درخواست‌ها، پاسخ‌ها، رویدادها و خطاهای مخصوص به خودشان را دارند.

اکس در سال ۱۹۸۴ و از موسسه فناوری ماساچوست سرچشچمه گرفته است. نسخه فعلی آن که X11 نام دارد، در سپتامبر ۱۹۸۷ به وجود آمده است. اینکه سیستم پنجره‌بندی اکس «مکانیسم و سازوکار را مشخص می‌کند، نه خط مشی را»، اصل اولیه‌ای بود که باب شیفلر و جیم گتیز، طراحان سیستم آن را برای سیستم انتخاب کردند. در نتیجه، پروتکل اصلی، چگونگی تعامل بین کلاینت‌ها یا بین یک کلاینت با یک کاربر را تعیین نمی‌کند. چگونگی انجام این تعامل‌ها در مشخصه‌های فنی دیگری بحث می‌شوند،[۴] همانند ICCCM و freedesktop.org و عموما وقتی که برنامه‌نویس تصمیم به استفاده از یک ابزار ویجت می‌گیرد، نحوه انجام این تعامل و خصوصیات هم به طور خودکار اعمال می‌شوند.

کلیات[ویرایش]

مثالی از تعامل بین کلاینت و سرور
در این مثال، سرور اکس از یک طرف با دستگاه‌های ورودی نظیر ماوس و کیبورد در ارتباط است و اطلاعات ورودی را از این دستگاه‌ها دریافت می‌کند؛ و از طرف دیگر با دستگاه‌های خروجی نظیر صفحه‌نمایش در ارتباط است و تصاویر خروجی را بر روی آن نمایش می‌دهد. یک مرورگر وب و یک شبیه‌ساز ترمینال هم در حال اجرا شدن بر روی رایانه کاربر هستند. در طرف دیگر و در یک رایانه که در راه دور قرار دارد، یک شبیه‌ساز ترمینال در حال اجرا شدن است. اما کنترل آن از روی رایانه کاربر صورت می‌گیرد، انگار که در حال اجرا شدن در همان ماشین محلی است.

ارتباط بین سرور و کلاینت‌ها با مبادله کردن بسته‌هایی بر روی یک کانال مخابراتی صورت می‌گیرد. اتصال توسط کلاینت برقرار می‌شود (چگونگی آغاز به کار کلاینت در پروتکل مشخص نشده است). همچنین کلاینت اولین بسته را هم ارسال می‌کند که این بسته، علاوه بر اینکه حاوی ترتیب بایت مورد استفاده است، اطلاعاتی درباره نسخه پروتکل و نحوه اعتبارسنجی که کلاینت انتظار دارد سرور از آن استفاده کند را هم در بر می‌گیرد. سرور در پاسخ بسته‌ای را برای کلاینت ارسال می‌کند که این بسته مشخص می‌کند آیا سرور اتصال کلاینت را پذیرفته است یا اینکه آن را رد کرده است و یا اینکه درخواستی برای اعتبار سنجی کلاینت را به همراه دارد. در صورتی که سرور اتصال را پذیرفته باشد، بسته حاوی داده‌هایی است که کلاینت باید در فعل و انفعالات بعدی با سرور از آنها استفاده کند. پس از اینکه اتصال برقرار شد، چهار نوع بسته در کانال ارتباطی بین سرور و کلاینت رد و بدل می‌شود:

  1. درخواست: کلاینت اطلاعاتی را از سرور درخواست می‌کند یا اینکه از سرور می‌خواهد تا عملیات خاصی را انجام دهد.
  2. پاسخ: سرور به درخواست پاسخ می‌دهد. تنها برخی از درخواست‌ها پاسخی را به همراه دارند، نه همه آنها.
  3. رویداد: سرور کلاینت را از رخ دادن رویدادی آگاه می‌کند، مثلاً ورودی ماوس یا صفحه کلید، جا به جا شدن یک پنجره، تغییر اندازه آن یا...
  4. خطا: در صورتیکه درخواست غیر مجاز تشخیص داده شود، سرور خطایی را ارسال می‌کند. از آنجا که درخواست‌ها در یک صف قرار می‌گیرند، خطایی که برای یک درخواست ارسال می‌شود ممکن است به صورت بلادرنگ ارسال نشود و تاخیری وجود داشته باشد.

درخواست‌ها و پاسخ‌ها طول متفاوتی دارند. این در حالی است که رویدادها یا خطاها از طول ثابت ۳۲ بایتی برخوردارند.

به محض اینکه سرور بسته‌های نوع درخواست را دریافت کرد، آنها را به ترتیب شماره گذاری می‌کند. به اولین درخواستی که از طرف کلاینت ارسال می‌شود شماره ۱ اختصاص می‌یابد، دومین درخواست شماره ۲ و الی آخر. ۱۶ بیت کم ارزش این عدد، در بسته‌های پاسخ یا بسته‌های خطایی که توسط درخواست تولید شده‌اند، در صورت وجود، گنجانده می‌شوند. این بیت‌ها همچنین در بسته‌های نوع رویداد هم به منظور نشان دادن شماره ترتیبی درخواستی که سرور حال پردازش آن است یا پردازش آن را به پایان رسانده، درج می‌شوند.

پنجره‌ها[ویرایش]

جایگیری پنجره‌ها در صفحه. شماره یک پنجره ریشه را نشان می‌دهد که کل صفحه را در بر گرفته است، ۲ و ۳ پنجره‌های سطح بالا هستند، ۴ و ۵ زیرپنجره‌های پنجره شماره ۲ هستند. آن قسمت از پنجره که خارج از پنجره والدش قرار دارد نمایش داده نمی‌شود.

چیزی که معمولاً در بسیاری از واسط‌های گرافیکی کاربر پنجره نامیده می‌شود، در سیستم پنجره اکس به آن پنجره سطح بالا[و ۶] می‌گویند. همچنین اصطلاح پنجره برای اشاره به پنجره‌هایی که در داخل یک پنجره دیگر قرار دارند هم بکار می‌رود. به پنجره‌ای که یک پنجره دیگر را دربرمی‌گیرد، پنجره والد[و ۷] و به پنجره‌ای که در داخل یک پنجره دیگر قرار گرفته زیرپنجره[و ۸] گفته می‌شود. عناصر گرافیکی نظیر دکمه‌ها، منوها، آیکون‌ها و غیره می‌توانند توسط زیرپنجره‌ها محقق شوند.

کلاینت می‌تواند درخواست کند که یک پنجره جدید ایجاد شود. همچنین کلاینت می‌تواند درخواست کند که یک زیرپنجره در داخل پنجره‌ای که از قبل وجود دارد ایجاد شود. در نتیحه، پنجره‌هایی که توسط کلاینت‌ها ایجاد می‌شوند، در یک ساختار درخت و به صورت سلسله مراتبی، مرتب می‌شوند. ریشه این درخت را پنجره ریشه تشکیل می‌دهد. پنجره ریشه یک پنجره خاص است و در هنگام آغاز به کار سیستم به شکل خودکار توسط سرور ایجاد می‌شود. تمامی پنجره‌های دیگر به شکل مستقیم یا غیر مستقیم فرزند پنجره ریشه هستند. پنجره‌های سطح بالا، فرزند مستقیم پنجره ریشه محسوب می‌شوند. از دید ظاهری، پنجره ریشه به بزرگی یک دسکتاپ مجازی است و در پشت تمام پنجره‌های دیگر نهفته می‌شود.

تضمینی برای حفظ دائمی محتویات یک پنجره وجود ندارد. محتویات یک پنجره می‌تواند با جابجا شدن پنجره، تغییر اندازه دادن پنجره، قرار گرفتن پنجره‌های دیگر بر روی آن پنجره، یا... نابود شده و تمام یا قسمتی از آن غیر قابل نمایش شود. اگر سرور یک انباره پشتیبان[و ۹] از محتوای یک پنجره را نگه نداشته باشد، محتوای یک پنجره ممکن است مفقود شود. کلاینت می‌تواند از سرور بخواهد که چنین انباره‌ای را از محتویات یک پنجره نگه‌داری کند، اما سرور تعهدی برای انجام این کار ندارد. در نتیجه، کلاینت‌ها نمی‌توانند چنین بپندارند که یک انباره پشتیبان برای یک پنجره نگه‌داری شده است. اگر قسمت نمایان یک پنجره، محتوای غیر مشخصی داشته باشد، رویدادی به کلاینت ارسال می‌شود و او را آگاه می‌کند که محتوای پنجره باید دوباره ترسیم شوند.

هر پنجره‌ای تعدادی صفت دارد. نظیر ژئومتری یک پنجره (که عبارتست از اندازه پنجره و مکان آن بر روی صفحه)، تصویر پس‌زمینه آن، اینکه آیا انباره پشتیبان برای آن نگهداری می‌شود یا نه و غیره. تعدادی درخواست برای بررسی کردن این صفت‌ها و تغییر دادن آنها در پروتکل تعبیه شده است.

پنجره‌ها می‌توانند به صورت InputOutput (هم ورودی داشته باشند و هم خروجی) و یا به شکل InputOnly (فقط ورودی داشته باشند) باشند. پنجره‌های InputOutput می‌توانند بر روی صفحه نمایش داده شوند و برای ترسیم کردن از آنها استفاده می‌شود. پنجره‌های InputOnly هیچگاه بر روی صفحه نمایش نمی‌یابند و از آنها تنها برای دریافت ورودی از کاربر استفاده می‌شود.

آناتومی یک پنجره در مدیر پنجره مجازی اف. قسمت سفید رنگ ناحیه‌ای است که توسط کلاینت ایجاد شده است. کلاینت پنجره را به صورت این ناحیه سفید رنگ می‌بیند. نوار عنوان پنجره دربرگیرنده نام پنجره و تعدادی دکمه برای مدیریت کردن پنجره است. قابی هم به دور پنجره کشیده شده است.

قاب زینتی و نوار عنوان پنجره‌ها (که می‌تواند شامل تعدادی دکمه هم باشد) که معمولا گرداگرد پنجره‌ها دیده می‌شوند، توسط مدیر پنجره رسم می‌شود، نه توسط کلاینتی که پنجره را ایجاد کرده و صاحب آن است. همچنین مدیر پنجره مسئول اداره کردن ورودی مرتبط با این اشیاء است. مثلا وقتی که کاربر با استفاده از نشانگر ماوس بر روی قاب پنجره کلید می‌کند و آن را تغییر اندازه دهد، این مدیر پنجره است که پنجره را کوچک و بزرگ می‌کند و آن را تغییر اندازه می‌دهد. کلاینت‌ها معمولا بدون توجه و در نظر گرفتن تغییرات انجام شده توسط مدیر پنجره، بر روی پنجره‌هایی که ایجاد کرده‌اند به فعالیت می‌پردازند. مدیر پنجره‌های ری-پارنتینگ پس از ایجاد کردن یک پنجره سطح بالا، والد آن پنجره را به پنجره‌ای غیر از پنجره ریشه تغییر می‌دهند. تقریبا تمام مدیر پنجره‌های مدرن، به صورت ری-پارنتینگ هستند. از دید پروتکل، مدیر پنجره هم تنها یک کلاینت است و با کلاینت‌های دیگر فرقی ندارد.

اطلاعات مربوط به یک پنجره را می‌توان توسط برنامه xwininfo بدست آورد. با ارسال آرگومان خط فرمانی ‎-tree به این برنامه، می‌توان درخت زیرپنجره‌های یک پنجره را به همراه شناسه‌ها و داده‌های ژئومتری آن پنجره‌ها مشاهده کرد.

پیکس‌مپ و ترسیم‌پذیرها[ویرایش]

یک پیکس‌مپ[و ۱۰] ناحیه‌ای از حافظه است که می‌توان از آن برای ترسیم استفاده کرد. برخلاف پنجره‌ها، پیکس‌مپ‌ها به شکل خودکار بر روی صفحه نمایش نمی‌یابند. با این حال محتوای یک پیکس‌مپ (یا قسمتی از آن) می‌تواند به یک پنجره منتقل شود (یا برعکس، محتوای یک پنجره به یک پیکس‌مپ منتقل شود). به کمک این کار می‌توان تکنیک‌هایی نظیر بافرینگ دوگانه را به اجرا درآورد. بسیاری از عملیات‌های گرافیکی که بر روی پنجره‌ها می‌توان انجام داد، بر روی پیکس‌مپ‌ها هم قابل انجام است.

پنجره‌ها و پیکس‌مپ‌ها مجموعاً ترسیم‌پذیر[و ۱۱] نامیده می‌شوند و محتوای آنها در سرور قرار داده می‌شود. با این حال، یک کلاینت می‌تواند درخواست کند که محتوای یک ترسیم‌پذیر از سرور به کلاینت یا از کلاینت به سرور منتقل شود.

بافت‌های گرافیکی و فونت‌ها[ویرایش]

کلاینت می‌تواند تعدادی عملیات گرافیکی از جمله پاک‌سازی یک ناحیه، کپی کردن محتوای یک ناحیه به ناحیه‌ای دیگر، رسم کردن نقطه، خط، مستطیل، متن و... را از سرور درخواست کند. علاوه بر پاک کردن، تمامی این عملیات‌ها بر روی تمام ترسیم‌پذیرها (پنجره و پیکس‌مپ) هم قابل انجام است.

بیشتر درخواست‌ها برای عملیات‌های گرافیکی، حاوی یک بافت گرافیکی[و ۱۲] هستند. بافت گرافیکی ساختاری است که دربرگیرنده پارامترهایی برای عملیات‌های گرافیکی است. یک بافت گرافیکی شامل رنگ پیش‌زمینه، رنگ پس‌زمینه، فونت متن و دیگر پارامترهای گرافیکی است. در هنگام درخواست دادن یک عملیات گرافیکی، کلاینت یک بافت گرافیکی را هم به همراه درخواست خود قرار می‌دهد. همه پارامترهای بافت گرافیکی بر روی عملیات‌ها تاثیر ندارند. برای مثال، فونت یک متن، تاثیری بر رسم کردن یک خط ندارد.

پروتکل، نحوه استفاده از فونت‌های سمت سرور را هم مشخص می‌کند.[۵] چنین فونت‌هایی به صورت فایل ذخیره می‌شوند و سرور به آنها یا به صورت مستقیم و از طریق سیستم فایل دسترسی دارد و یا به آنها به شکل غیر مستقیم و از طریق شبکه و برنامه‌ای که سرویس‌دهنده فونت[و ۱۳] نامیده می‌شود، دسترسی دارد. کلاینت‌ها می‌توانند فهرست تمام فونت‌های موجود را از سرور درخواست کنند و پس از اینکه فونتی را از لیست انتخاب کردند، می‌توانند از سرور بخواهند که آن فونت را بارگذاری کند (اگر هنوز بارگذاری نشده باشد) یا آن فونت را باراندازی[و ۱۴] کند (اگر کلاینت‌های دیگر در حال استفاده از آن نباشند). یک کلاینت می‌تواند اطلاعات کلی درباره یک فونت و همینطور مقدار فضایی که یک رشته متنی خاص در حین رسم شدن با آن فونت نیاز دارد را از سرور درخواست کند. در سطح پروتکل، نام فونت‌ها می‌تواند رشته‌های دلخواهی باشد. در قرارداد توصیف منطقی فونت‌های اکس نحوه نام‌گذاری فونت‌ها بر اساس خصوتیاتشان مشخص شده است.[۶] این قرارداد همچنین مقادیر دلخواهی که می‌توانند به فونت‌ها ضمیمه شوند را هم مشخص می‌کنند.

برنامه xlsfonts لیست فونت‌هایی که در سرور ذخیره شده‌اند را چاپ می‌کند.

در حال حاضر، با وجود فونت‌های سمت کلاینت، استفاده از فونت‌های سمت سرور منسوخ شده است.[۷] فونت‌های سمت کلاینت توسط خود کلاینت رندر می‌شوند و سرور آنها را رندر نمی‌کند. کتابخانه اکس‌اف‌تی، کایرو و افزونه اکس‌رندر چنین پشتیبانی را فراهم می‌کنند. مشخصات این فونت‌ها در پروتکل اصلی تعریف و مشخص نشده است.

منابع و شناسه‌ها[ویرایش]

تمامی داده‌های مربوط پنجره‌ها، پیکس‌مپ‌ها، فونت‌ها و... در سرور ذخیره می‌شوند. کلاینت شناسه این اشیا را می‌داند. شناسه‌ها اعداد صحیحی هستند که به یک شی اختصاص می‌یابند و به عنوان نام آن شی مورد استفاده قرار می‌گیرند. کلاینت‌ها از این شناسه‌ها برای تعامل با سرور استفاده می‌کنند. به عنوان مثال، اگر یک کلاینت بخواهد که پنجره جدید رسم شود، شناسه آن پنجره را، به همراه درخواستی برای ایجاد یک پنجره جدید، به سرور ارسال می‌کند. کلاینت بعدها می‌تواند از این شناسه استفاده کرده و برای مثال، از سرور بخواهد که رشته‌ای را در آن پنجره رسم کند. اشیاء زیر در سرور قرار دارند و کلاینت آنها را با استفاده از یک شناسه عددی می‌شناسد:

  • Window
  • Pixmap
  • Font
  • Colormap (جدولی از رنگ‌ها، بعداً تشریح می‌شود)
  • Graphic context

این اشیا، منبع نامیده می‌شوند. وقتی که کلاینت درخواست ایجاد یک چنین منبعی را می‌دهد، شناسه آن را هم مشخص می‌کند. به عنوان مثال، برای ایجاد یک پنجره جدید، کلاینت هم صفات پنجره نظیر پنجره والد، طول، عرض و... را مشخص می‌کند و هم شناسه‌ای که قرار است به آن پنجره اختصاص یابد را مشخص می‌کند.

شناسه‌ها اعداد صحیح ۳۲ بیتی هستند که سه بیت پر ارزش آنها صفر است. هر کلاینت مجموعه شناسه‌های مخصوص به خود را دارد که می‌تواند برای ایجاد کردن اشیا از آنها استفاده کند. این مجموعه توسط سرور مشخص می‌شود. سرور این مجموعه شناسه را با ارسال دو عدد صحیح در بسته پذیرش (همان بسته‌ای که سرور در ابتدای کار در جواب کلاینت برای ایجاد اتصال جدید، برای او ارسال می‌کند) مشخص می‌کند. کلاینت شناسه‌های خود را از طوری از این مجموعه انتخاب می‌کند که برخوردی پیش نیاید: در بین پنجره‌ها، پیکس‌مپ‌ها، فونت‌ها، رنگ‌نگاشت‌ها و بافت‌های گرافیکی، دو شی دارای شناسه یکسانی نباشند.

بعد از اینکه یک منبع ایجاد شد، کلاینت می‌تواند با استفاده از شناسه آن شی، از سرور درخواست کند که عملیاتی را بر روی آن شی انجام دهد. برخی از درخواست‌ها، بر روی منبع تاثیر می‌گذارند (برای مثال، درخواست جابجا کردن یک پنجره)؛ برخی دیگر، اطلاعاتی که درباره یک منبع در سرور ذخیره شده را درخواست می‌دهند (نظیر درخواست برای خصوصیات یک پنجره).

شناسه‌ها نه تنها در کلاینت، بلکه در سرور هم یکتا و منحصربه‌فرد هستند. برای مثال، دو پنجره مختلف هیچگاه شناسه یکسانی ندارند، حتی اگر دو کلاینت مختلف آنها را ایجاد کرده باشند. یک کلاینت می‌تواند با دادن شناسه هر شیئی به آن دسترسی داشته باشد. یک کلاینت می‌تواند به اشیائی که توسط دیگر کلاینت‌ها ایجاد شده‌اند هم دسترسی داشته باشد، حتی اگر شناسه آن شی، خارج از محدوده شناسه‌های آن کلاینت باشد.

در نتیجه، دو کلاینت مختلف که هر دو به یک سرور متصل هستند، می‌توانند از یک شناسه مشترک برای دسترسی داشتن به یک شی یکسان استفاده کنند. برای مثال اگر کلاینتی یک شی با شناسه 0x1e00021 ایجاد کرده باشد و این عدد 0x1e00021 را در اختیار یک برنامه دیگر قرار دهد (به هر شکل دلخواهی، مثل ذخیره کردن این عدد در یک فایل به صورتی که برنامه دیگر بتواند شناسه را از آن فایل بخواند)، برنامه دیگر هم قادر خواهد بود تا بر روی همان پنجره عملیاتی را انجام دهد. به عنوان مثال برنامه گوست‌ویو در سیستم پنجره اکس از این قابلیت به این صورت بهره می‌برد: این برنامه یک زیر پنجره ایجاد می‌کند، سپس شناسه آن را در یک متغیر محیطی ذخیره می‌کند، سپس برنامه گوست‌اسکریپت را فراخوانی می‌کند، برنامه گوست‌اسکریپت محتوای یک فایل پست‌اسکریپت را در این پنجره نمایش می‌دهد.[۸]

معمولاً وقتی که یک کلاینت اتصالش را با سرور قطع می‌کند، منابع بوجود آمده توسط آن کلاینت نابود می‌شوند. با این حال، یک کلاینت قبل از خاتمه دادن به اتصال، می‌تواند از سرور بخواهد که منابع را نابود نکند.

رویدادها[ویرایش]

مثالی از یک رویداد: وقتی که کلیدی در یک پنجره فشرده می‌شود، بسته به ماسک رویداد آن پنجره، رویدادی تولید شده و به کلاینت ارسال می‌شود. این ماسک رویداد را کلاینت می‌تواند تغییر داده و انتخاب کند که آیا مایل به دریافت آن رویداد است یا نه

رویدادها، بسته‌هایی هستند که از طرف سرور برای کلاینت ارسال می‌شوند، این بسته‌ها کلاینت را از رخ دادن اتفاقی که ممکن است برای کلاینت جالب توجه باشد، آگاه می‌کنند. به عنوان مثال، وقتی که کاربر کلیدی را فشار می‌دهد یا بر روی دکمه‌ای کلیک می‌کند، رویدادی برای کلاینت ارسال می‌شود. رویدادها فقط برای ورودی گرفتن از کاربر و فعل و انفعالات او استفاده نمی‌شوند. برای مثال، وقتی که زیرپنجره‌ای در یک پنجره ایجاد می‌شود، رویدادی برای آگاه کردن کلاینت از این اتفاق، برای آن ارسال می‌شود.

هر رویدادی با یک پنجره در ارتباط است. برای مثال، اگر کاربر در حالی که نشانگر ماوس بر روی یک پنجره قرار دارد، روی آن پنجره کلیک کند، رویداد با آن پنجره در ارتباط خواهد بود. بستهٔ رویدادی که برای کلاینت ارسال می‌شود، حاوی شناسه آن پنجره است.

یک کلاینت می‌تواند از سرور بخواهد که رویدادی را برای یک کلاینت دیگر ارسال کند؛ کلاینت‌ها از این قابلیت برای برقراری ارتباط با یکدیگر استفاده می‌کنند. به عنوان مثال، یک چنین رویدادی وقتی تولید می‌شود که کلاینتی درخواست می‌کند متنی که در حال حاضر توسط کاربر انتخاب شده است، برایش ارسال شود؛ این رویداد به کلاینتی ارسال می‌شود که پنجره‌ای که حاوی متن انتخاب شده است را اداره می‌کند.

هنگامی که محتویات ناحیه‌ای در یک پنجره، نابود شده و سپس مجددا نمایان می‌شود، رویدادی به نام Expose به کلاینت فرستاده می‌شوند. محتوای یک پنجره می‌تواند در بعضی شرایط نابود شود. مثلا اگر یک پنجره، بر روی پنجره دیگری قرار گیرد و کل و یا قسمتی از آن را بپوشاند، محتوای پنجره پوشیده شده نابود خواهد شد. البته این در صورتی است که سرور انباره پشتیبان برای آن پنجره را نگه‌داری نداشته باشد. سرور تضمین نمی‌کند که حتما یک انباره پشتیبان نگه‌داری می‌کند، اما تضمین می‌کند که هر گاه نیاز به ترسیم مجدد محتوای یک پنجره باشد، رویدادی را برای کلاینت ارسال کند.

بسیاری از رویدادها تنها وقتی به کلاینت ارسال می‌شوند که کلاینت آمادگی خود را از قبل برای دریافت آنها اعلام کرده باشد و مایل به دریافت آن رویداد باشد. دلیل این کار این است که شاید تنها چند نوع رویداد خاص برای برخی کلاینت‌ها جالب توجه باشد و کلاینت‌ها نخواهند به همه آنها پاسخ دهند. برای مثال، یک کلاینت ممکن است تنها بخواهد از رویدادهای مرتبط با صفحه کلید آگاه شود و علاقه‌ای به رویدادهای مرتبط با ماوس نداشته باشد. با این حال رویدادهایی هستند که حتی اگر کلاینت از قبل آمادگی خود را برای دریافت آنها نشان نداده باشد، باز هم برای کلاینت ارسال می‌شوند.

کلاینتها با تنظیم کردن یکی از خصوصیات پنجره، مشخص می‌کنند که علاقه‌مند به دریافت چه نوع رویدادهایی هستند. به عنوان مثال، به منظور ترسیم مجدد پنجره‌ای که محتوای آن نابود شده، کلاینت باید رویداد Expose را دریافت و قبول کند (این رویداد برای همین منظور در نظر گرفته شده و به کلاینت اطلاع می‌دهد که محتوای پنجره نیازمند ترسیم مجدد هستند). با این حال، این رویداد تنها وقتی برای کلاینت ارسال می‌شود که کلاینت از قبل اعلام کرده باشد که می‌خواهد آن را دریافت کند. این کار با تنظیم کردن خصوصیت ماسک رویداد پنجره با مقدار مناسب صورت می‌گیرد.

کلاینت‌های مختلف می‌توانند رویدادهای مرتبط با یک پنجره یکسان را دریافت کنند. آنها حتی می‌توانند ماسک رویداد آن پنجره را به شکل متفاوتی مقدار دهی کنند و بدین ترتیب، هر کدام رویدادهای متفاوتی را دریافت کنند. به عنوان مثال، یک کلاینت شاید بخواهد تنها رویدادهای مرتبط با صفحه کلیدی که برای یک پنجره اتفاق می‌افتد را دریافت کند، در حالی که کلاینت دیگر دوست دارد تنها رویدادهای مرتبط با ماوس را برای همان پنجره دریافت کند. این کار به این خاطر امکان‌پذیر است که سرور برای هر پنجره، ماسک رویداد مجزایی را به ازای هر کلاینت نگه‌داری می‌کند. با این حال برخی از رویدادها تنها می‌توانند در هر زمان توسط یک کلاینت دریافت شوند و کلاینت دیگر نمی‌تواند همزمان همان رویداد را دریافت کند. این رویدادها، گزارش‌هایی را درباره کلیک کردن دکمه‌های ماوس و همینطور تغییراتی درباره مدیریت پنجره ارسال می‌کنند.

برنامه xev رویدادهای مرتبط با یک پنجره را نمایش می‌دهد. دستور xev -id WID تمام رویدادهای ممکن برای پنجره‌ای با شناسه WID را دریافت کرده و چاپ می‌کند.

مثال[ویرایش]

در ادامه مثالی از نحوه معامل و برقراری ارتباط بین کلاینت و سرور را مرور می‌کنیم. در این مثال، کلاینت یک پنجره ایجاد می‌کند که جعبه‌ای سیاه رنگ در آن قرار دارد، برنامه به محض فشردن شدن یک کلید، خارج می‌شود. در این مثال، سرور هیچ پاسخی به طرف کلاینت ارسال نمی‌کند، چرا که درخواست‌های کلاینت پاسخی را تولید نمی‌کنند. اما این درخواست‌ها می‌توانند باعث به وقوع پیوستند یک خطا شوند:

  1. کلاینت اتصال جدیدی را با سرور ایجاد کرده و بسته آغازینی را برای سرور ارسال می‌کند. این بسته حاوی اطلاعاتی نظیر ترتیب بایت مورد استفاده توسط کلاینت، نسخه پروتکل و... است.
  2. سرور با ارسال یک بسته مناسب برای کلاینت، اتصال را می‌پذیرد (در این مثال نیازی به اعتبار سنجی و احراز هویت نیست). این بسته دربرگیرنده شناسه پنجره ریشه (در اینجا 0x0000002b) و محدوده‌ای از شناسه‌هاست که کلاینت می‌تواند از آنها برای نام‌گذاری کردن منابع و اشیا استفاده کند.
  3. کلاینت درخواست می‌کند که یک بافت گرافیکی پیشفرض با شناسه 0x00200000 ایجاد شود. (این درخواست، همانند درخواست‌های دیگر این مثال، پاسخی را در بر ندارد)
  4. کلاینت از سرور می‌خواهد که یک پنجره سطح بالا ایجاد کند. (در این مثال، کلاینت شناسه پنجره ریشه که 0x0000002b بود را به عنوان پنجره والد مشخص می‌کند، شناسه خود پنحره سطح بالا را 0x00200001 درنظر می‌گیرد، اندازه پنجره را ۲۰۰ در ۲۰۰ پیکسل مشخص می‌کند و از سرور می‌خواهد تا این پنجره را در مختصات (۱۰٫۱۰) رسم کند)
  5. کلاینت از سرور می‌خواهد که یکی از خصوصیات پنجره‌ای با شناسه 0x00200001 را تغییر دهد، و مشخص می‌کند که دوست دارد رویدادهای KeyPress و Expose را دریافت کند. اگر این رویدادها اتفاق افتادند، سرور کلاینت را با ارسال یک بسته مناسب آگاه می‌کند.
  6. کلاینت از سرور می‌خواهد پنجره‌ای که شناسه آن 0x00200001 است بر روی صفحه نقش شود (بر روی صفحه نشان داده شود).
  7. وقتی که پنجره بر روی صفحه نمایان شد و نیاز به ترسیم محتوای آن بود، سرور رویداد Expose را برای کلاینت ارسال می‌کند.
  8. در پاسخ به این رویداد، کلاینت با ارسال کردن یک درخواست PolyFillRectangle از سرور می‌خواهد جعبه‌ای بر روی پنجره رسم شود. شناسه این پنجره 0x00200001 و شناسه بافت گرافیکی آن 0x00200000 است.

اگر پنجره دیگری بر روی پنجره قرار گیرد و مجدداً از روی آن برداشته شود، با فرض اینکه انباره پشتیبان نگه داری نشده باشد:

  1. سرور یک رویداد Expose دیگر ارسال می‌کند تا به کلاینت بگوید که محتوای پنجره باید مجددا رسم شوند.
  2. کلاینت مجدداً درخواست PolyFillRectangle را به سرور ارسال می‌کند.

اگر کلیدی فشرده شود:

  1. سرور یک رویداد KeyPress برای کلاینت ارسال می‌کند تا او را از فشرده شدن کلیدی آگاه کند.
  2. کلاینت پاسخ مناسبی برای آن رویداد ارسال خواهد کرد. (در این مثال، به اجرای خودش خاتمه خواهد داد)

رنگ‌ها[ویرایش]

در سطح پروتکل، رنگ‌ها به شکل اعداد صحیح ۳۲ بیتی بدون علامت نمایش می‌یابند که pixelvalue نامیده می‌شوند. عناصر زیر بر روی نمایش رنگ‌ها تاثیر دارند:

  • عمق رنگ
  • رنگ‌نگاشت[و ۱۵] که جدولی است که شدت رنگ‌های آبی، قرمز، سبز در آن مشخص می‌شود.
  • گونه بصری[و ۱۶] که مشخص می‌کند چگونه جدول رنگ‌نگاشت باید برای نمایش رنگ‌ها مورد استفاده قرار گیرد.

در ساده‌ترین حالت، رنگ‌نگاشت جدولی است که هر سطر آن حاوی یک سه‌تایی آرجی‌بی است. یک pixelvalue به نام x، نشان‌دهنده رنگی است که در سطر xام جدول قرار گرفته است. اگر کلاینت قادر باشد مدخل‌های رنگ‌نگاشت را تغییر دهد، این بازنمایش جدید توسط کلاس بصری[و ۱۷] PseudoColor نشان داده می‌شود. کلاس StaticColor هم کلاسی مشابه است، اما در این کلاس کلاینت نمی‌تواند مدخل‌های رنگ‌نگاشت را تغییر دهد.

حدود ۶ کلاس بصری وجود دارد که هر کدام از آنها روش متفاوتی را برای نمایش دادن سه‌تایی RGB در یک pixelvalue دارند. PseudoColor و StaticColor دو تا از این کلاس‌ها هستند. GrayScale و StaticGray هم دو تای دیگر هستند فرق آنها در این است که این جدول‌ها فقط شدت رنگ قهوه‌ای را نمایش می‌دهند.

دو کلاس بصری باقی‌مانده با کلاس‌هایی که در بالا معرفی شدند متفاوت هستند، چرا که آن‌ها pixelvalueها را به سه قسمت تقسیم می‌کنند و برای تعیین کردن شدت رنگ‌های آبی، قرمز و سبز، از سه جدول مجزا برای هر کدام استفاده می‌کنند. بر طبق این نحوه نمایش رنگ، یک pixelvalue به صورت زیر به یک سه‌تایی RGB تبدیل می‌شود:

  1. pixelvalue به صورت دنباله‌ای از بیت‌ها در نظر گرفته می‌شود.
  2. این دنباله به سه دسته تقسیم می‌شود.
  3. هر کدام از این سه دسته بیت، به صورت یک عدد صحیح درمی‌آید و سپس به عنوان یک اندیس، به منظور پیدا کردن یک مقدار در یکی از آن سه جدول مجزا، مورد استفاده قرار می‌گیرد.

این مکانیسم نیازمند آن است که رنگ‌نگاشت از سه جدول مجزا تشکیل شده باشد و به ازای هر رنگ اولیه یک جدول وجود داشته باشد. نتیجه این تبدیل، همچنان یک سه‌تایی از مقادیری است که مشخص کننده شدت رنگ‌ها هستند. کلاس‌های بصری که برای نمایش این تبدیل جدید استفاده می‌شود DirectColor و TrueColor هستند و فرق آنها در این است که آیا کلاینت می‌تواند رنگ‌نگاشت‌ها را تغییر دهد یا خیر.

این شش مکانیسم برای نمایش رنگ‌ها بوسیله pixelvalueها همگی نیازمند پارامترهای بیشتری هستند تا بتوانند کار کنند. این پارامترها در یک گونه بصری فراهم می‌شوند که حاوی یک کلاس بصری و دیگر پارامترهای مورد نیاز برای نمایش رنگ‌هاست. هر سرور یک دسته ثابت از گونه‌های بصری دارد که هر کدام شناسه عددی مخصوص به خود را دارند. این شناسه‌ها اعداد صحیح ۳۲ بیتی بدون علامت هستند، اما الزاما متفاوت با شناسه منابع یا اتم‌های (بعدا تشریح می‌شود) دیگر نیستند و ممکن است با آنها همپوشانی داشته باشند.

وقتی که اتصال یک کلاینت توسط سرور پذیرفته می‌شود، بسته پذیرشی که از طرف سرور برای کلاینت ارسال می‌شود حاوی دنباله‌ای از بلاک‌هاست که هر کدام از این بلاک‌ها حاوی اطلاعاتی درباره یک صفحه نمایش هستند. بلاک متناظر با هر صفحه نمایش، حاوی فهرستی از بلاک‌های دیگر است که هر کدام از این بلاک‌ها مربوط به عمق رنگ خاصی هستند که ان صفحه نمایش از آن پشتیبانی می‌کند. این فهرست به ازای هر یک از عمق رنگ‌های مورد پشتیبانی، حاوی فهرستی از گونه‌های بصری است. در نتیجه، هر صفحه نمایش تعدادی عمق رنگ دارد که هر کدام از عمق رنگ‌ها دارای چند گونه بصری هستند. هر گونه بصری را می‌توان برای چندین صفحه‌نمایش با عمق‌های مختلف مورد استفاده قرار داد.

برای هر گونه بصری، بسته پذیرش هم حاوی شناسه آن گونه بصری هست و هم حاوی پارامترهای واقعی که در آن وجود دارد. کلاینت این اطلاعات را در خود ذخیره می‌کند، چرا که بعدا نمی‌توانند آنها را درخواست دهند. علاوه بر آن، کلاینت‌ها نمی‌توانند گونه‌های بصری را تغییر داده یا گونه‌های بصری جدید ایجاد کنند. درخواستی که برای ایجاد کردن یک پنجره جدید ارسال می‌شود، حاوی عمق و شناسه گونه بصری‌ای است که برای نمایش دادن رنگ‌ها در آن پنجره باید استفاده شوند.

رنگ‌ها بدون در نظر گرفتن اینکه سخت‌افزاری که صفحه نمایش را کنترل می‌کند (همانند کارت گرافیک) از یک پالت استفاده می‌کند یا نه، مورد استفاده قرار می‌گیرند. پالت هم جدولی است که برای نمایش دادن رنگ‌ها استفاده می‌شود. حتی اگر سخت‌افزار از یک پالت استفاده نکند، سرورهاباز هم از رنگ‌نگاشت‌ها استفاده می‌کنند. هنگامی که سخت‌افزار از پالت استفاده می‌کند، تنها تعداد محدودی از رنگ‌نگاشت‌ها را می‌توان بکار گرفت. به خصوص، یک رنگ‌نگاشت وقتی به کار گرفته می‌شود که سخت‌افزار بر طبق آن رنگ‌ها را نشان می‌دهد. یک کلاینت می‌تواند از سرور بخواهد که یک رنگ‌نگاشت را بکار بگیرد. با این حال این کار ممکن است نیازمند از کار انداختن رنگ‌نگاشت دیگری باشد. این کار باعث می‌شود پنجره‌هایی که از آن رنگ‌نگاشت از کار انداخته شده استفاده می‌کنند، با رنگ‌های مناسب خود نمایش نیابند که به آن color flashing یا technicolor می‌گویند. این مشکل می‌تواند با استفاده از رنگ‌نگاشت‌های استاندارد رفع شود. رنگ‌نگاشت‌های استاندارد رنگ‌نگاشت‌هایی هستند که در انها رابطه‌ای بین pixelvalueها و رنگ‌ها وجود دارد. به لطف این خصیصه در رنگ‌نگاشت‌های استاندارد، می‌توانند توسط برنامه‌های مختلفی بکار گرفته شوند.

بوجود آوردن رنگ‌نگاشت‌ها در قرارداد ICCCM بحث شده است. رنگ‌نگاشت‌های استاندارد توسط ICCCM و اکس‌لیب تنظیم می‌شوند.

اتم‌ها[ویرایش]

اتم‌ها اعداد ۳۲ بیتی هستند که رشته‌ها را نمایش می‌دهند. طراحان پروتکل اتم‌ها را به این دلیل معرفی کردند، که اتم‌ها رشته‌ها را به شکلی کوتاه و با اندازه‌ای ثابت نمایش می‌دهند.[۹] در حالی که یک رشته می‌تواند طول دلخواهی داشته باشد، یک اتم همیشه اندازه ثابت ۳۲ بیتی دارد. در بسته‌هایی که یک رشته مشابه باید به صورت چند باره ارسال شود، می‌توان با استفاده از اتم‌ها، از شبکه به شکل بهینه‌تر استفاده کرد.

به شکل دقیقتر می‌توان گفت که اتمها همان شناسه‌هایی برای رشته‌ها هستند که در سرور ذخیره می‌شوند. آنها مشابه شناسه‌های منابع (پنجره، پیکس‌مپ و غیره) هستند. اما به دو شکل با آنها متفاوت هستند. یکی اینکه شناسه اتم‌ها توسط سرور انتخاب می‌شود و کلاینت در انتخاب آنها نقشی ندارد. به عبارتی دیگر، وقتی که کلاینت درخواست ایجاد یک اتم جدید را می‌دهد، تنها رشته‌ای که قرار است ذخیره شود را برای سرور ارسال می‌کند، نه شناسه آن را. این شناسه توسط سرور انتخاب شده و به عنوان پاسخ برای کلاینت ارسال می‌شود. دومین فرق مهم بین اتم‌ها و منابع این است که اتم‌ها با کلاینتها در ارتباط نیستند و با آنها آمیخته نمی‌شوند. وقتی که اتم‌ها در سرور ایجاد می‌شوند، تا وقتی که سرور خاموش یا راه‌اندازی مجدد نشده، در همان‌جا باقی خواهند ماند (منابع به شکل پیشرض چنین رفتاری ندارند).

از آنجا که اتم‌ها شناسه هستند، منحصر به فرد و یکتا هم هستند. با این حال، یک اتم و شناسه یک منبع می‌تواند با هم همپوشانی داشته باشند. رشته‌ای که به یک اتم اختصاص یافته، نام اتم نامیده می‌شود. بعد از اینکه یک اتم ایجاد شد، نام آن را نمی‌توان تغییر داد و دو اتم هم نمی‌توانند نام یکسانی داشته باشند. در نتیجه، معمولا از نام یک اتم برای اشاره به آن اتم استفاده می‌شود. «اتم ABCD» به شکل دقیقتر یعنی «اتمی که رشته ABCD به آن اختصاص یافته است». یک کلاینت، هم می‌تواند از سرور درخواست کند که یک اتم جدید ایجاد کند و هم می‌تواند با دادن یک رشته به سرور، شناسه اتم آن را دریافت کند. برخی از اتم‌ها از قبل تعریف شده هستند. (سرور آنها را با یک شناسه و رشته معین از قبل تعریف کرده است).

از اتم‌ها می‌توان برای اهداف مختلفی استفاده کرد. یکی از رایج‌ترین استفاده از اتم‌ها، برقرار کردن ارتباط بین دو یا چند کلاینت است که هر همگی به یک سرور مشابه متصل شده‌اند. آنها به همراه ویژگی‌های پنجره‌ها استفاده می‌شوند که در ادامه تشریح می‌شود.

با استفاده از برنامه xlsatoms می‌توان لیست تمام اتم‌های موجود در سرور را چاپ کرد. این برنامه برای هر اتم، شناسه آن (که یک عدد است) و نام آن (که یک رشته است) را چاپ می‌کند.

خصیصه‌ها[ویرایش]

هر پنجره، یک سری ویژگی[و ۱۸] از پیش تعریف شده و یک سری خصیصه[و ۱۹] دارد که همه آنها در سرور ذخیره می‌شوند و کلاینت می‌تواند برای دسترسی به آنها، درخواست مناسبی را برای سرور ارسال کند. ویژگی‌ها، اطلاعاتی درباره یک پنجره هستند، مثل اندازه، مکان، رنگ پس‌زمینه و غیره. خصیصه‌ها، اطلاعات دلخواهی هستند که به یک پنجره ضمیمه می‌شوند. برخلاف ویژگی‌ها، خصیصه‌ها معنی خاصی در سطح پروتکل اکس ندارند. یک کلاینت می‌تواند هر گونه اطلاعات دلخواهی را در خصیصه یک پنجره ذخیره کند.

یک خصیصه توسط نام، نوع و مقدار آن توصیف می‌شود. خصیصه‌ها شبیه به متغیرها در زبان‌های برنامه‌نویسی دستوری هستند، که یک کلاینت می‌تواند خصیصه جدیدی را با نام و نوع دلخواه ایجاد کرده و مقداری را در آن ذخیره کند. خصیصه‌ها مخصوص همان پنجره هستند: دو خصیصه همنام می‌تواند در دو پنجره متفاوت وجود داشته باشد، در حالی که مقدار و نوع آنها با یکدیگر متفاوت است.

نام، نوع و مقدار یک خصیصه به صورت رشته، یا به شکل دقیق‌تر، اتم هستند. رشته‌ها در سرور ذخیره شده و کلاینت می‌تواند از طریق شناسه‌ها به آن‌ها دسترسی داشته باشد. یک کلاینت می‌تواند با استفاده از شناسهٔ اتمی که دربرگیرنده نام یک خصیصه است، به آن خصیصه دسترسی داشته باشد.

خصیصه‌ها بیشتر به منظور ارتباطات بین کلاینتی استفاده می‌شوند. برای مثال، یک خصیصه به نام WM_NAME (این خصیصه توسط اتمی که رشته اختصاص یافته به آن "WM_NAME" است نامگذاری شده است) وجود دارد که برای ذخیره کردن اسامی پنجره‌ها استفاده می‌شود. مدیر پنجره‌ها معمولا این خصیصه را می‌خوانند و سپس آن را در نوار عنوان پنجره نمایش می‌دهند.

برخی از انواع ارتباطات بین کلاینتی، از خصیصه‌های پنجره ریشه استفاده می‌کنند. برای مثال، بر طبق مشخصاتی که فری‌دسکتاپ[۱۰] برای مدیر پنجره‌ها تعریف کرده، مدیر پنجره‌ها باید شناسه پنجره‌ای که در حال حاضر فعال است و فوکوس را در اختیار دارد را در یکی از خصیصه‌های پنجره ریشه به نام ‎_NET_ACTIVE_WINDOW ذخیره کنند. منابع اکس که حاوی پارامترهای برنامه‌ها هستند هم در خصیصه‌های پنجره ریشه ذخیره می‌شوند. به این ترتیب، همه کلاینت‌ها می‌توانند به این خصیصه‌ها دسترسی داشته باشند، حتی اگر آنها بر روی رایانه‌های مختلفی اجرا شوند.

برنامه xprop خصیصه‌های یک پنجره خاص را نمایش می‌دهد. دستور xprop -root، نام، نوع و مقدار تمام خصیصه‌های پنجره ریشه را چاپ می‌کند.

نگاشت کردن[ویرایش]

این کلید همیشه یک keycode یکسان را تولید می‌کند، اما keysymهای مختلفی برای به نماد /، 7 و } وجود دارد.

در سیستم پنجره‌بندی اکس، هر کلیدی که بر روی دستگاه‌های ورودی از جمله ماوس و کیبورد وجود دارد، یک عدد منحصربفرد مابین ۸ تا ۲۵۵ دارد که به آن keycode می‌گویند. یک keycode تنها یک کلید خاص را شناسایی می‌کند، نه یک کاراکتر یا لفظ (مثل Page up) که بر روی کلید چاپ شده‌اند را. درعوض هر کدام از این الفاظ یا کاراکترها با یک keysym شناسایی می‌شوند. در حالیکه keycode تنها به کلیدی که فشرده شده است وابسته است، یک keysym ممکن است به اینکه دکمه Shift یا یک اصلاح‌گر[و ۲۰] دیگر هم فشرده شده باشد، بستگی داشته باشد.

وقتی که کلیدی فشرده یا رها می‌شود، سرور رویدادهایی از نوع KeyPress یا KeyRelease را برای کلاینت‌های مورد نظر ارسال می‌کند. این رویدادها حاوی موارد زیر هستند:

  • keycode کلیدی که فشرده شده است.
  • وضعیت فعلی اصلاح‌گرها (شیفت، کنترل و ...) و دکمه‌های ماوس
چگونگی ترجمه شدن یک keycode به یک keysym

بنابراین سرور keycode و وضعیت اصلاح‌گرها را بدون اینکه سعی کند آنها را به یک کاراکتر خاص ترجمه کند، برای کلاینت ارسال می‌کند و وظیفه ترجمه و تفسیر آنها بر عهده کلاینت است. برای مثال یک کلاینت ممکن است رویدادی مبنی بر اینکه یک کلید خاص در حالی فشرده شده است که دکمه شیفت هم پایین نگه داشته شده، دریافت کند. اگر در حالت معمول این کلید خاص کاراکتر 'a' را تولید می‌کرده، کلاینت (و نه سرور) این رویداد را به منزله وارد شدن کاراکتر 'A' تلقی می‌کند.

در حالیکه ترجمه keycodeها به keysym توسط کلاینت صورت می‌گیرد، جدولی که ارتباط بین آنها را مشخص می‌کند در سرور قرار دارد. ذخیره کردن این جدول در سرور که یک جای عمومی و مرکزی است، این امکان را فراهم می‌کند تا همه کلاینت‌ها بتوانند به آن دسترسی داشته باشند. کلاینت‌ها تنها از سرور نگاشت کردن keycodeها به keysymها را درخواست می‌کنند و از آن برای رمزگشایی کردن keycodeها و اصلاح‌گرها به یک keysym استفاده می‌کنند. با این حال، کلاینت‌ها می‌توانند این نگاشت کردن را به خواست خودشان تغییر دهند.

یک اصلاح‌گر کلیدی است که وقتی فشرده می‌شود، نوع تفسیر شدن کلیدها را تغییر می‌دهد. یکی از اصلاح‌گرهای رایج، کلید شیفت است. وقتی که کلیدی که در حالت معمول کاراکتر 'a' را تولید می‌کند، به همراه کلید شیفت فشرده می‌شود، باعث تولید شدن یک کاراکتر بزرگ 'A' می‌شود. دیگر اصلاح‌گرهای رایج، کلید آلت، کنترل و متا[و ۲۱] هستند.

سرور اکس حداکثر با هشت عدد اصلاح‌گر کار می‌کند. ضمنا، هر اصلاح‌گر می‌تواند بیش از یک کلید داشته باشد. این کار لازم است چرا که بیشتر کیبوردها دو کلید برای برخی از اصلاح‌گرها دارند. برای مثال، بیشتر کیبوردها دو کلید شیفت دارند (یکی در سمت چپ و دیگری در سمت راست). این دو کلید، در هنگام فشرده شدن هر کدام keycode خاص و متفاوت از یکدیگری را تولید می‌کنند، اما سرور اکس هر دو آنها را به عنوان اصلاح‌گر شیفت می‌شناسد.

سرور اکس برای هر کدام از این هشت اصلاح‌گر، فهرستی از keycodeها را نگه می‌دارد که آنها را به عنوان آن اصلاح‌گر تفسیر می‌کند. به عنوان مثال، اگر در فهرست اولین اصلاح‌گر (اصلاح‌گر شیفت)، یک kecode با مقدار 0x37 وجود داشته باشد، آنگاه سرور کلیدی که باعث تولید شدن keycodeای با مقدار 0x37 می‌شود را به عنوان یک کلید شیفت در نظر می‌گیرد.

هرچند که فهرست‌های مربوط به نگاشت کردن اصلاح‌گرها در سرور نگهداری می‌شود، اما هر کلاینتی می‌تواند آنها را مطابق با خواست خود تغییر دهد. به عنوان مثال، یک کلاینت می‌تواند در خواست دهد که کلید F1 به فهرست اصلاح‌گر شیفت اضافه شود. با این کار، کلید F1 همانند یک کلید شیفت عمل می‌کند. با این حال، keycode اصلی متناظر با F1 همچنان در حین فشرده شدن این کلید تولید می‌شود. در نتیجه، F1 همانگونه عمل می‌کند که قبلا عمل می‌کرده (برای مثال ممکن است یک پنجره Help در حین فشرده شدن F1 باز شود)، اما همچنین به عنوان یک کلید شیفت هم عمل می‌کند (مثلا فشردن کلید 'a' به همراه F1 می‌تواند باعث تولید شدن یک کاراکتر 'A' در یک ویرایشگر متن شود).

سرور اکس همچنین مکانیزمی برای نگاشت کردن دکمه‌های ماوس دارد. با این حال، دکمه‌های ماوس تنها می‌توانند جایگذاری شوند. این کار خصوصا برای تعویض کردن دکمه‌های چپ و راست برای استفاده راحت‌تر توسط افراد راست‌دست و چپ‌دست مفید است.

قاپیدن رویدادها[ویرایش]

اگر مکان‌نما یا کیبورد فریز شده باشد، رویدادها همچنان تولید می‌شود، اما در یک صف ذخیره می‌شوند تا وقتی که از حالت فریز خارج شوند و آنگاه برای کلاینت مورد نظر ارسال می‌شوند. اگر آنها گرب شده باشند، رویدادهای مرتبط با آنها به جای اینکه برای پنجره‌ای که در حالت عادی آنها را دریافت می‌کند، ارسال شود، برای کلاینتی که گرب را در اختیار دارد ارسال می‌شود. رویدادهای مرتبط با مکان‌نما را می‌توان بسته به یک ماسک رویداد دور انداخت.

قاپیدن رویدادها[و ۲۲] وضعیتی است که در آن تمام رویدادهای مربوط به کیبورد و ماوس، تنها به یک کلاینت خاص ارسال می‌شود. به عبارت دیگر، یک کلاینت رویدادهایی که در اصل برای کلاینت‌های دیگر هستند را از آنها می‌قاپد. کلاینت می‌تواند درخواست قاپیدن رویدادهای کیبورد، ماوس یا هر دو را از سرور درخواست کند. اگر سرور درخواست کلاینت را برآورده سازد، آنگاه تمام رویدادهای مربوط به ماوس/کیبورد به آن کلاینت ارسال می‌شود تا وقتی که کلاینت grab را رها کند. کلاینت‌های دیگر این رویدادها را دریافت نخواهند کرد.

کلاینت در هنگام قاپیدن رویدادها، پنجره قاپیدن را هم مشخص می‌کند. در این حالت، تمام رویدادها طوری به کلاینت ارسال می‌شوند که انگار مرتبط با آن پنجره قاپیدن هستند. با این حال دیگر کلاینت‌ها هیچ رویدادی را دریافت نمی‌کنند، حتی اگر آن رویدادها را در پنجره قاپیدن انتخاب کرده باشند. دو نوع قاپیدن وجود دارد:

  • اکتیو: قاپیدن رویدادها بلافاصله صورت می‌گیرد.
  • پسیو: تنها زمانی صورت می‌گیرد که یک کلید خاص از کیبورد یا یک دکمه خاص از ماوس (که از قبل تعیین شده) فشرده شود و وقتی که کلید رها شد، قاپیدن رویدادها هم پایان می‌یابد.

کلاینت‌ها می‌توانند بر روی کیبورد، مکان‌نما یا هر دو آنها درخواست قاپیدن رویدادها را بکنند. یک درخواست قاپیدن می‌تواند حاوی درخواستی برای فریز کردن صفحه‌کلید یا مکان‌نما باشد. تفاوت گرب کردن (قاپیدن رویدادها) و فریز کردن در این است که در گرب، گیرنده رویدادها تغییر می‌کند و رویدادها به کلاینتی غیر از کلاینت اصلی‌شان تحویل داده می‌شوند، در حالی که فریز کردن باعث می‌شود تا رویدادها به هیچ گیرنده‌ای تحویل داده نشوند. وقتی که دستگاهی فریز می‌شود، رویدادهایی که آن دستگاه تولید می‌کند در یک صف ذخیره می‌شوند تا بعدها پس از اتمام شدن عمل فریز، به گیرنده تحویل داده شوند.

در مورد رویدادهای مربوط به مکان‌نما، پارامتر دیگری هم وجود دارد که در تحویل دادن رویدادها موثر است: یک ماسک رویداد، که مشخص می‌کند چه نوع رویدادهایی باید تحویل داده شوند و از چه نوع رویدادهایی باید صرف نظر شده و دور انداخته شوند.

دیگر موارد[ویرایش]

رویدادها و درخواست‌های دیگری هم در پروتکل وجود دارد. برخی از درخواست‌ها در مورد رابطه والدیت بین پنجره‌ها هستند. یک کلاینت می‌تواند درخواست کند تا والد یک پنجره تغییر یابد. یا می‌تواند اطلاعاتی را در مورد والد یک پنجره درخواست کند. برخی دیگر از درخواست‌ها، در مورد انتخاب‌ها هستند، با این حال، اکثر این درخواست‌ها توسط پروتکل‌های دیگری غیر از پروتکل اصلی اداره می‌شوند. دسته دیگر از درخواست‌ها، درخواست‌های مرتبط با فوکوس ورودی و شکل مکان‌نما هستند. همچنین یک کلاینت می‌تواند درخواست دهد مالک یک منبع (پنجره، pixmap و ...)، از بین برود که خود باعث از بین رفتن ارتباط سرور با آن می‌شود. در نهایت، یک کلاینت می‌تواند یک درخواست از نوع بدون عملیات را برای سرور ارسال کند.

اضافات و افزونه‌ها[ویرایش]

افزونه shape به پنجره ساعت اجازه می‌دهد تا یک پنجره گرد و مدور ایجاد کند که فاقد قاب و نوار عنوان است.

پروتکل سیستم پنجره اکس به صورت توسعه‌پذیر و قابل گسترش طراحی شده است. این پروتکل مکانیزمی را فراهم می‌کند که یک کلاینت به کمک آن می‌تواند از وجود داشتن یک افزونه مطمئن شود. همینطور پروتکل اصلی، چگونگی ایجاد شدن بسته‌های درخواست، رویداد و خطایی که متعلق به یک افزونه هستند را هم مشخص می‌کند.

یک کلاینت می‌تواند برای داده‌هایی که وابسته و مرتبط به یک افزونه خاص هستند، لیست تمام افزونه‌های موجود را درخواست کند. بسته‌هایی که متعلق به یک افزونه هستند، مشابه همان بسته‌های اصلی پروتکل هستند. پروتکل اصلی، مشخص می‌کند که بسته‌های نوع درخواست، رویداد یا خطا، باید دربرگیرنده یک عدد صحیح باشند که این عدد صحیح، نوع آن بسته را مشخص می‌کند (برای مثال، درخواست‌هایی که برای ایجاد یک پنجره جدید بکار می‌روند، با عدد ۱ شماره‌گذاری می‌شوند). محدوده‌ای از این اعداد صحیح برای افزونه‌ها رزرو شده‌اند.

اعتبارسنجی و تایید هویت[ویرایش]

در ابتدا وقتی که کلاینت قصد دارد ارتباطی را با سرور برقرار کند، سرور می‌تواند ارتباط را بپذیرد، آن را رد کند، یا کلاینت را اعتبارسنجی کند و در صورت تایید شدن هویت کلاینت، ارتباط با آن را بپذیرد. روش‌های متفاوتی برای اعتبار سنجی وجود دارد. یک درخواست اعتبارسنجی، حاوی روش مورد استفاده برای اعتبارسنجی است و روش انجام این کار در درخواست مشخص می‌شود. پروتکل مراحل اعتبار سنجی را مشخص نمی‌کند، چرا که مراحل اعتبارسنجی بستگی به روشی دارد که برای اعتبارسنجی استفاده می‌شود، پروتکل تنها مشخص می‌کند که این فرایند یا با ارسال بسته پذیرش و یا با ارسال بسته عدم پذیرش از سوی سرور، خاتمه می‌یابد.

در طول یک فعل و انفعال عادی بین یک کلاینت و سرور، تنها درخواست‌هایی که با اعتبارسنجی در ارتباط هستند، در مورد روش دسترسی مبتنی بر میزبان[و ۲۳] هستند. به طور دقیق‌تر، یک کلاینت می‌تواند از سرور بخواهد که این روش فعال باشد یا نه، و همینطور می‌تواند از سرور بخواهد که فهرستی از میزبان‌هایی (کلاینت‌هایی) که مجاز به برقراری ارتباط هستند را بخواند و یا تغییر دهد. برنامه‌های عادی از این‌گونه درخواست‌ها استفاده نمی‌کنند، این درخواست‌ها توسط برنامه xhost استفاده می‌شوند. این برنامه از این درخواست‌ها به این منظور استفاده می‌کند تا به یک کاربر یا یک اسکریپت، اجازه دسترسی داشتن به سرور اکس را بدهد.

اکس‌لیب و دیگر کتابخانه‌های مرتبط[ویرایش]

نوشتار اصلی: اکس‌لیب

بیشتر برنامه‌های کلاینت با استفاده از کتابخانه اکس‌لیب با سرور ارتباط برقرار می‌کنند. در واقع، عمده کلاینت‌ها از کتابخانه‌های جی‌تی‌کی، کیوت، موتیف و ... استفاده می‌کنند که این کتابخانه‌ها خود در واقع در سطوح پایین‌تر از اکس‌لیب برای برقراری ارتباط با سرور استفاده می‌کنند. استفاده از اکس‌لیب اثرات زیر را بدنبال دارد:

  1. اکس‌لیب کلاینت را نسبت به پاسخ‌ها و رویدادها همگام می‌کند:
    1. توابعی که در اکس‌لیب درخواستی به طرف سرور ارسال می‌کنند، تا زمانی که پاسخ مناسب از طرف سرور برسد، بلوکه می‌شوند. به عبارت دیگر، کلاینتی که از اکس‌لیب استفاده نمی‌کند می‌تواند درخواستی را ارسال کند و سپس به انجام کارهای دیگری بپردازد تا وقتی که پاسخ درخواست را از سرور دریافت کند. اما کلاینتی که از اکس‌لیب استفاده می‌کند تنها می‌تواند درخواستی را برای سرور ارسال کند و منتظر رسیدن پاسخ آن بماند و از این رو کلاینتی که منتظر رسیدن پاسخ درخواستش است، بلوکه می‌شود (مگر اینکه کلاینت قبل از فراخوانی تابع، یک ریسه جدید را اجرا کرده باشد)
    2. هنگامی که سرور رویدادها را به صورت ناهمگام ارسال می‌کند، اکس‌لیب رویدادهای دریافت شده توسط کلاینت را در یک صف ذخیره می‌کند. کلاینت تنها می‌تواند با فراخوانی کردن صریح توابعی خاص در اکس‌لیب به این رویدادهای موجود در صف دسترسی داشته باشد. به عبارت دیگر، اگر کلاینت منتظر یک رویداد باشد، مجبور به بلوکه شدن و یا کشیدن انتظار مشغول می‌شود.
  2. اکس‌لیب درخواست‌ها را بلافاصله برای سرور ارسال نمی‌کند، ابتدا آنها را در یک صف ذخیره می‌کند که به آن بافر خروجی[و ۲۴] می‌گویند، سپس در یکی از حالات زیر درخواست‌های موجود در این بافر ارسال می‌شود:
    1. برنامه با فراخوانی کردن یک تابع خاص به نام XFlush صریحا از اکس‌لیب بخواهد که این کار را انجام دهد.
    2. برنامه تابعی مانند XGetWindowAttributes را فراخوانی کند که سرور در نتیجه فراخوانی این تابع، پاسخی را ارسال کند.
    3. برنامه رویدادی را از صف رویدادها درخواست دهد (برای مثال با XNextEvent) و آن فراخوانی مسدود شود (برای مثال اگر صف خالی باشد XNextEvent مسدود می‌شود)

کتابخانه‌های سطح بالاتر همانند Xt (که خود توسط موتیف و Xaw مورد استفاده قرار می‌گیرد)، به برنامه‌های کلاینت اجازه می‌دهد تا برای برخی از رویدادها، توابع بازفراخوانی[و ۲۵] را در نظر بگیرند. این کتابخانه به صف رویدادها سرکشی می‌کند و در هنگام نیاز، توابع منظور شده را اجرا می‌کند. برخی از رویدادها، همانند رویدادهایی که نیازمند ترسیم مجدد یک پنجره هستند، به صورت توکار توسط Xt مدیریت می‌شوند.

کتابخانه‌های سطح پایین همانند XCB، دسترسی ناهمگام به پروتکل را میسر می‌سازند، که باعث می‌شود تاخیر زمانی پنهان بماند.

بخش‌های تشریح‌نشده[ویرایش]

پروتکل اصلی سیستم پنجره‌بندی اکس در مورد ارتباطات بین کلاینتی حکم نمی‌کند و مشخص نمی‌کند که برای بوجود آوردن عناصر بصری رایج در واسط‌های گرافیکی کاربر (دکمه‌ها، منوها و ...)، چگونه باید پنجره‌ها را مورد استفاده قرار داد. این عناصر توسط کتابخانه‌های سمت کلاینت مشخص و تعریف می‌شوند. ارتباطات بین کلاینتی توسط استانداردهای دیگری مثل ICCCM و مشخصه‌های freedesktop مورد پوشش قرار می‌گیرد.[۱۰]

ارتباطات بین کلاینتی با سلکشن‌ها، کات بافرها، و عمل drag-and-drop در ارتباط است که این موارد روش‌هایی هستند که یک کاربر می‌تواند از آنها برای منتقل کردن داده‌ها از یک کلاینت به کلاینت دیگر استفاده کند. از آنجا که پنجره‌ها ممکن است توسط برنامه‌های مختلفی کنترل شوند، پروتکلی برای انتقال دادن این داده‌ها مورد نیاز است تا هماهنگی و ارتباط بین برنامه‌ها برقرار شود. ارتباطات بین کلاینتی همچنین با مدیر پنجره‌های اکس هم در ارتباط است. مدیر پنجره‌ها برنامه‌هایی هستند که ظاهر پنجره‌ها و نما و حس کلی رابط کاربری را تحت کنترل دارند. مبحث مرتبط دیگر در ارتباطات بین کلاینتی، مبحث مدیریت جلسه یا مدیریت نشست است.

چگونگی آغاز یک نشست کاربری، مسئله دیگری است که در پروتکل اصلی در مورد آن بحث نشده است. عموما این کار به صورت خودکار توسط مدیر نشست اکس اداره می‌شود. با این حال کاربر می‌تواند به صورت دستی هم نشستی را با اجرای برنامه‌های startx و xinit آغاز نماید.

واژه‌نامه[ویرایش]

  1. asynchronously
  2. request
  3. reply
  4. event
  5. error
  6. top-level window
  7. parent window
  8. sub-window
  9. backing store
  10. pixmap
  11. drawable
  12. Graphic context
  13. font server
  14. unload
  15. colormap
  16. visual type
  17. visual class
  18. Attribute
  19. property
  20. modifier
  21. Meta
  22. Grab
  23. host-based access method
  24. output buffer
  25. callback

منابع[ویرایش]

  1. Robert W. Scheifler and James Gettys: X Window System: Core and extension protocols, X version 11, releases 6 and 6.1, Digital Press 1996, ISBN 1-55558-148-X
  2. RFC 1013
  3. Grant Edwards. An Introduction to X11 User Interfaces
  4. Jim Gettys. Open Source Desktop Technology Road Map
  5. comp.fonts FAQ: X11 Info
  6. Jim Flowers; Stephen Gildea (1994). "X Logical Font Description Conventions" (PDF). Digital Equipment Corporation. X Consortium. Retrieved 2005-12-30. 
  7. Matthieu Herrb and Matthias Hopf. New Evolutions in the X Window System.
  8. Ghostview: Interface with ghostscript
  9. David Rosenthal. Inter-Client Communication Conventions Manual. MIT X Consortium Standard, 1989
  10. ۱۰٫۰ ۱۰٫۱ Freedesktop window manager specification

پیوند به بیرون[ویرایش]