پروتکل اصلی سامانه پنجرهای اکس[1][2][3] (به انگلیسی: X Window System core protocol) پایهایترین پروتکل در ساختار سامانه پنجرهای اکس است. سامانهٔ پنجرهای اکس، یک سامانه پنجرهای تحت شبکه برای نمایشگرهای بیتمپی است که برای ساختن واسطهای گرافیکی کاربر در سیستمعاملهای یونیکس، شبه یونیکس یا دیگر سیستمها بکار برده میشود. اکس بستری را فراهم میکند که بهکمک آن میتوان نرمافزارهایی به همراه واسط گرافیکی (همچون میزکارهای گنوم و کیدیئی) را بر روی این سیستمعاملها اجرا کرده و توسعه داد. سامانهٔ پنجرهای اکس از یک مدل مشتری-خدمتگذار برخوردار است. در این مدل، یک سرویسدهندهٔ یگانه که سرور اکس نامیده میشود، همهٔ سختافزارهای ورودی/خروجی همانند صفحه نمایش، صفحه کلید، ماوس و ... را کنترل میکند. همهٔ برنامههای کاربردی هم به گونهٔ سرویسگیرنده کار میکنند و با کمک سرور اکس، با کاربر یا دیگر کلاینتها تعامل برقرار میکنند. این تعامل توسط پروتکل اصلی سامانه پنجرهای اکس ساماندهی میشود. پروتکلهای دیگری هم در رابطه با سامانه پنجرهای اکس وجود دارد که این پروتکلها، هم به گونهٔ یک پروتکل جدا و خودسر هستند و هم اینکه بر روی بستر پروتکل اصلی اکس ایجاد شدهاند.
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/9/95/X11.svg/150px-X11.svg.png)
در پروتکل اصلی سامانهٔ پنجرهای اکس، تنها چهار گونه بسته وجود دارد که به گونهٔ ناهمگام،[و 1] بر روی شبکه فرستاده میشود: درخواستها،[و 2] پاسخها،[و 3] رویدادها[و 4] و خطاها.[و 5] درخواستها از سوی کلاینت به سرور فرستاده میشوند تا اجرای یک کار یا دریافت اطلاعاتی را از سرور درخواست کنند. درخواستها یا به سرور میگویند که کار خاصی را انجام دهد (همچون ایجاد کردن یک پنجره تازه) یا از سرور میخواهند که دادههای دلخواهی را برای کلاینتها بفرستد. پاسخها از سوی سرور برای کلاینتها فرستاده میشوند و دادههای درخواستی کلاینت را در خود دارند که در پاسخ به درخواست کلاینتها برای آنها فرستاده میشود. رویدادها از سوی سرور برای کلاینت فرستاده میشوند و کلاینت را از کارهایی که کاربر سرگرم انجامدادن آنهاست یا رخدادهای دیگری که ممکن است کلاینت علاقهمند به دانستن آنها باشد، باخبر میکنند و کلاینت میتواند واکنش درخور به آن رویدادها را نشان دهد. هنگامی که رویداد غیرمنتظرهای در هنگام پردازش کردن درخواستهای کلاینت رخ میدهد و خطایی روی میدهد، سرور این خطاها را به کمک بستههایی از نوع خطا به آگاهی کلاینت میرساند. درخواستها ممکن است باعث تولید کردن پاسخها، رویدادها یا خطاها شوند؛ افزون بر آن، سرور اجبار نمیکند که بستهها حتماً باید به ترتیب خاصی بر روی شبکه ارسال شوند. چندین افزونه برای پروتکل اصلی هست که هر کدام درخواستها، پاسخها، رویدادها و خطاهای ویژهٔ خودشان را دارند.
اکس در سال ۱۹۸۴ و از مؤسسه فناوری ماساچوست سرچشمه گرفتهاست. نسخهٔ کنونی آن که X11 نام دارد، در سپتامبر ۱۹۸۷ ساخته شدهاست. اینکه سامانه پنجرهای اکس «مکانیسم و سازوکار را مشخص میکند، نه خط مشی را»، اصل اولیهای بود که طراحان سیستم، باب شیفلر و جیم گتیز، آن را گزیدند. در نتیجه، پروتکل اصلی، چگونگی تعامل بین کلاینتها یا تعامل بین یک کلاینت با یک کاربر را تعیین نمیکند. چگونگی انجام این تعاملها در مشخصههای فنی دیگری بحث میشوند،[4] همانند ICCCM و freedesktop.org و عموماً هنگامی که برنامهنویس تصمیم به استفاده از یک ابزار ویجت میگیرد، چگونگی انجام این تعامل و خصوصیات هم خودکار اعمال میشوند.
کلیات
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Xcore-overview_fa.svg/320px-Xcore-overview_fa.svg.png)
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/0/03/X_client_server_example.svg/220px-X_client_server_example.svg.png)
اکس از یک مدل سرویسگیرنده-سرویسدهنده[و 6] برخوردار است. سرور اکس برنامهایست که بر روی رایانهای که دارای نمایشگر و کیبورد است، نصب میشود. سرور اکس درخواستها را از کلاینتها دریافت کرده، پس از پردازش، آنها را بر روی صفحهنمایش (یا دیگر دستگاههای خروجی) نمایش میدهد. همچنین سرور اکس اطلاعات را از ماوس و کیبورد و دیگر دستگاههای ورودی دریافت کرده، آنها را برای کلاینتها میفرستد. کلاینتها همان برنامههای کاربردی مانند فایرفاکس، لیبرهآفیس و ... هستند. ارتباط بین کلاینتها و سرور به کمک پروتکلهای شبکه انجام میشود؛ بنابراین این دو برنامه میتوانند بر روی کامپیوترهای گوناگون که حتی سیستمعاملهای ناهمسانی هم دارند، نصب شده و سپس با هم تعامل داشته باشند.
ارتباط بین سرور و کلاینتها با مبادله کردن بستههایی بر روی یک کانال مخابراتی انجام میشود. اتصال از سوی کلاینت برقرار میشود (چگونگی آغاز به کار کلاینت در پروتکل مشخص نشدهاست). همچنین کلاینت نخستین بسته را هم میفرستد که این بسته، افزون بر اینکه ترتیب بایت بکاررفته را در خود دارد، اطلاعاتی دربارهٔ نسخهٔ پروتکل و چگونگی اعتبارسنجی که کلاینت دوست دارد سرور از آن استفاده کند را هم در بر میگیرد. سرور در پاسخ بستهای را برای کلاینت میفرستد که این بسته مشخص میکند آیا سرور اتصال کلاینت را پذیرفتهاست یا اینکه آن را رد کردهاست یا اینکه درخواستی برای اعتبارسنجی کلاینت را به همراه دارد. اگر سرور اتصال را پذیرفته باشد، بسته، دادههایی در خود دارد که کلاینت باید در کنشهای آینده با سرور، آنها را بکار برد. پس از اینکه اتصال برپا شد، چهار گونه بسته در کانال ارتباطی بین سرور و کلاینت جابجا میشود:
- درخواست: کلاینت اطلاعاتی را از سرور درخواست میکند یا اینکه از سرور میخواهد تا کاری را انجام دهد.
- پاسخ: سرور به درخواست کلاینت پاسخ میدهد. تنها برخی از درخواستها پاسخی را به همراه دارند، نه همه آنها.
- رویداد: سرور کلاینت را از رخ دادن رویدادی آگاه میکند، همچون ورودی ماوس یا صفحه کلید، جابجا شدن یک پنجره، تغییر اندازه آن و دیگر چیزها.
- خطا: اگر درخواست غیرمجاز شمرده شود، سرور خطایی را برای کلاینت میفرستد. از آنجایی که درخواستها در یک صف جاداده میشوند، خطایی که برای یک درخواست فرستاده میشود ممکن است بیدرنگ فرستاده نشوند و دیرکردی در کار باشد.
درخواستها و پاسخها طول گوناگون و غیرثابتی دارند. این در حالی است که رویدادها یا خطاها از طول ثابت ۳۲ بایتی برخوردارند.
همینکه سرور بستههای «درخواست» را دریافت کرد، آنها را به ترتیب شمارهگذاری میکند. به نخستین درخواستی که از سوی کلاینت فرستاده میشود، شماره ۱ واگذار میشود، دومین درخواست شماره ۲ و همینگونه تا به پایان. اگر درخواستی، یک پاسخ یا یک خطا را به بار آورد، ۱۶ بیت کمارزش از شمارهای که به آن درخواست داده شده، در آن بستهٔ «پاسخ» یا «خطا» گنجانده میشود تا مشخص باشد که این «پاسخ» یا «خطا» برای کدام درخواست است. این بیتها همچنین در بستههای «رویداد» هم برای نشان دادن شمارهٔ درخواستی که سرور سرگرم پردازش آن است یا پردازش آن را به پایان رسانده، گنجانده میشوند.
پنجرهها
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/4/49/Some_X_windows.svg/320px-Some_X_windows.svg.png)
چیزی که در بسیاری از واسطهای گرافیکی کاربر پنجره نامیده میشود، در سامانهٔ پنجرهای اکس به آن پنجره سطح بالا[و 7] میگویند. همچنین اصطلاح پنجره برای نامیدن پنجرههایی که در درون یک پنجره دیگر جای دارند هم بکار میرود. به پنجرهای که یک پنجره دیگر را دربرمیگیرد، پنجره پدر[و 8] و به پنجرهای که درون یک پنجره دیگر جای گرفته زیرپنجره[و 9] گفته میشود. عناصر گرافیکی همچون دکمهها، منوها، آیکونها و دیگر چیزها، میتوانند بهدست زیرپنجرهها محقق شوند.
کلاینت میتواند از سرور درخواست کند که یک پنجره تازه ساخته شود. همچنین کلاینت میتواند درخواست کند که یک زیرپنجره در درون پنجرهای که از پیش وجود دارد، ساخته شود. در نتیجه، پنجرههایی که بهدست کلاینتها ساخته میشوند، در یک ساختار درختی و به گونهٔ سلسلهمراتبی، چیده میشوند. ریشهٔ این درخت، پنجره ریشه است. پنجره ریشه یک پنجرهٔ ویژه است و در هنگام آغاز به کار سیستم به گونه خودکار بهدست سرور ساخته میشود. همه پنجرههای دیگر به گونه مستقیم یا غیرمستقیم فرزند پنجره ریشه هستند. پنجرههای سطح بالا، فرزند مستقیم پنجره ریشه شمرده میشوند. از دید ظاهری، پنجره ریشه به بزرگی یک دسکتاپ مجازی است و در پشت همه پنجرههای دیگر نهفته میشود.
تضمینی برای نگهداری همیشگی محتویات و درونمایهٔ یک پنجره در کار نیست. درونمایهٔ یک پنجره میتواند با جابجا شدن پنجره، تغییر اندازه دادن پنجره، گذاشتن پنجرههای دیگر بر روی آن پنجره، یا ... نابود شده و همه یا بخشی از آن نمایشناپذیر شود. اگر سرور یک انباره پشتیبان[و 10] از درونمایهٔ یک پنجره را نگه نداشته باشد، درونمایهٔ یک پنجره ممکن است از دست برود. کلاینت میتواند از سرور بخواهد که چنین انبارهای را از درونمایهٔ یک پنجره نگهداری کند، اما سرور تعهد و ضمانتی برای انجام این کار ندارد. در نتیجه، کلاینتها نمیتوانند چنین بپندارند که سرور یک انباره پشتیبان برای یک پنجره را نگهداری میکند. اگر بخش نمایان یک پنجره، درونمایهٔ نامشخصی داشته باشد، رویدادی برای کلاینت فرستاده میشود و او را آگاه میکند که درونمایهٔ پنجره باید دوباره ترسیم شوند.
هر پنجرهای تعدادی صفت دارد. همانند ژئومتری (اندازه پنجره و جای آن بر روی صفحه)، تصویر پسزمینه آن، اینکه آیا انباره پشتیبان برای آن نگهداری میشود یا نه و صفتهای دیگر. تعدادی درخواست برای بررسی کردن این صفتها و تغییر دادن آنها در پروتکل تعبیه شدهاست.
پنجرهها میتوانند به گونه InputOutput
(هم ورودی داشته باشند و هم خروجی) یا به گونه InputOnly
(تنها ورودی) باشند. پنجرههای InputOutput
میتوانند بر روی صفحه نمایش داده شوند و برای ترسیم کردن بکار برده میشوند. پنجرههای InputOnly
هیچگاه بر روی صفحه نمایش نمییابند و آنها تنها برای دریافت ورودی از کاربر بکاربرده میشوند.
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Xframe_%28en%29.png/640px-Xframe_%28en%29.png)
قاب زینتی و نوار عنوان پنجرهها (که میتواند شامل شماری دکمه هم باشد) که گرداگرد پنجرهها دیده میشود، بهدست برنامهای ویژه به نام مدیر پنجره رسم میشود، نه بهدست کلاینتی که پنجره را ساخته و صاحب آن است. همچنین این مدیر پنجره است که مسئول سرپرستی کردن ورودی مرتبط با این عناصر است. برای نمونه، هنگامی که کاربر با نشانگر ماوس بر روی قاب پنجره کلیک میکند و آن را تغییر اندازه میدهد، در واقع این مدیر پنجره است که پنجره را کوچک و بزرگ میکند و آن را تغییر اندازه میدهد. کلاینتها معمولاً بدون توجه و در نظر گرفتن تغییرات انجام شده بهدست مدیر پنجره، بر روی پنجرههایی که ساختهاند به فعالیت میپردازند. مدیر پنجرههای ری-پرنتینگ[و 11] پس از ساختن یک پنجره سطح بالا، پدر این پنجره تازهایجادشده را به پنجرهای جز پنجرهٔ ریشه، که برای همین منظور در نظر گرفته شده، تغییر میدهند. تقریباً همه مدیر پنجرههای نوین، ری-پرنتینگ هستند. از دید پروتکل، مدیر پنجره هم تنها یک کلاینت است و با کلاینتهای دیگر فرقی ندارد.
اطلاعات مربوط به یک پنجره را میتوان با برنامه xwininfo
بهدست آورد. با فرستادن آرگومان خط فرمانی -tree
به این برنامه، میتوان درخت زیرپنجرههای یک پنجره را به همراه شناسهها و دادههای ژئومتری آن پنجرهها دید.
پیکسمپ و ترسیمپذیرها
یک پیکسمپ[و 12] بخشی از حافظه است که میتوان آن را برای ترسیم کردن بکار برد. برخلاف پنجرهها، پیکسمپها به گونه خودکار بر روی صفحه، نمایش نمییابند. با این حال، محتوای یک پیکسمپ (یا بخشی از آن) میتواند به یک پنجره منتقل شود (یا برعکس، محتوای یک پنجره به یک پیکسمپ برده شود). به کمک این کار، میتوان شگردهایی همچون بافرینگ دوگانه را به اجرا درآورد. بسیاری از عملیاتهای گرافیکی که بر روی پنجرهها میتوان انجام داد، بر روی پیکسمپها هم انجامپذیر است.
پنجرهها و پیکسمپها روی هم ترسیمپذیر[و 13] نامیده میشوند و محتوای آنها در سرور جای داده میشود. با این حال، یک کلاینت میتواند درخواست کند که محتوای یک ترسیمپذیر از سرور به کلاینت یا از کلاینت به سرور جابجا شود.
بافتهای گرافیکی و فونتها
کلاینت میتواند شماری عملیات گرافیکی همچون پاکسازی یک بخش، کپی کردن درونمایهٔ یک بخش به بخشی دیگر، رسم کردن نقطه، خط، مستطیل، متن و... را از سرور درخواست کند. افزون بر پاک کردن، همه این عملیاتها بر روی همه ترسیمپذیرها (پنجره و پیکسمپ) هم انجامپذیر است.
بیشتر درخواستهایی که کلاینت برای انجام عملیاتهای گرافیکی به سرور میفرستد، یک بافت گرافیکی[و 14] در خود دارند. بافت گرافیکی ساختاری است که دربرگیرنده پارامترهایی برای عملیاتهای گرافیکی است. یک بافت گرافیکی رنگ پیشزمینه، رنگ پسزمینه، فونت متن و دیگر پارامترهای گرافیکی را در خود دارد. در هنگام درخواست دادن یک عملیات گرافیکی، کلاینت یک بافت گرافیکی را هم به همراه درخواست خود برای سرور میفرستد. همه پارامترهای بافت گرافیکی بر روی همه عملیاتها تأثیرگذار نیستند. برای نمونه، فونت یک متن، تأثیری بر روی رسم کردن یک خط ندارد.
پروتکل، چگونگی بکاربردن فونتهای سمت سرور را هم تعریف و مشخص میکند.[5] چنین فونتهایی به گونه فایل ذخیره میشوند و سرور به آنها یا به صورت مستقیم و با سیستم فایل دسترسی دارد یا به آنها به گونه غیرمستقیم و با شبکه و برنامهای که سرویسدهنده فونت[و 15] نامیده میشود، دسترسی دارد. کلاینتها میتوانند فهرست همه فونتهای موجود را از سرور درخواست کنند و پس از اینکه فونتی را از فهرست برگزیدند، میتوانند از سرور بخواهند که آن فونت را بارگذاری کند (اگر هنوز بارگذاری نشده باشد) یا آن فونت را باراندازی[و 16] کند (اگر کلاینتهای دیگر سرگرم استفاده از آن نباشند). یک کلاینت میتواند اطلاعات کلی دربارهٔ یک فونت و همچنین مقدار فضایی که یک رشته متنی خاص در هنگام رسم شدن با آن فونت نیاز دارد را از سرور درخواست کند. در سطح پروتکل، نام فونتها میتواند رشتههای دلخواهی باشد. در قرارداد توصیف منطقی فونتهای اکس چگونگی نامگذاری فونتها بر اساس خصوتیاتشان مشخص شدهاست.[6] این قرارداد همچنین مقادیر دلخواهی که میتوانند به فونتها چسبیده شوند را هم مشخص میکنند.
برنامه xlsfonts
فهرست فونتهایی که در سرور ذخیره شدهاند را چاپ میکند.
هماکنون، با وجود فونتهای سمت کلاینت، فونتهای سمت سرور منسوخ شدهاند.[7] فونتهای سمت کلاینت بهدست خود کلاینت رندر میشوند و سرور آنها را رندر نمیکند. کتابخانه اکسافتی، کایرو و افزونه اکسرندر چنین پشتیبانی را فراهم میکنند. مشخصات این فونتها در پروتکل اصلی تعریف و مشخص نشدهاست.
منابع و شناسهها
همه دادههای مربوط پنجرهها، پیکسمپها، فونتها و ... در سرور ذخیره میشوند. کلاینت شناسه این اشیاء را میداند. شناسهها، اعداد صحیحی هستند که به یک شی داده میشوند و به عنوان نام آن شی بکار برده میشوند. کلاینتها از این شناسهها برای تعامل با سرور استفاده میکنند. برای نمونه، اگر یک کلاینت بخواهد که پنجره تازه رسم شود، شناسه آن پنجره را، به همراه درخواستی برای ساختن یک پنجره نو، برای سرور میفرستد. کلاینت پس از آن میتواند این شناسه را بکار برده و برای نمونه، از سرور بخواهد که رشتهای متنی را در آن پنجره چاپ کند. اشیاء زیر در سرور قرار دارند و کلاینت آنها را با یک شناسه عددی میشناسد:
- پنجره
- پیکسمپ
- فونت
- رنگنگاشت (جدولی از رنگها، بعداً تشریح میشود)
- بافت گرافیکی
این اشیاء، منبع[و 17] نامیده میشوند. هنگامی که کلاینت درخواست ساختن یک چنین منبعی را میدهد، شناسه آن را هم مشخص میکند. برای نمونه، برای ساختن یک پنجره تازه، کلاینت هم صفات پنجره، همچون پنجره ودر، درازا، پهنا و... را مشخص میکند و هم شناسهای که قرار است به آن پنجره داده شود را مشخص میکند.
شناسهها اعداد صحیح ۳۲ بیتی هستند که سه بیت پرارزش آنها صفر است. هر کلاینت، مجموعه شناسههای ویژه خود را دارد که میتواند برای ساختن اشیاء آنها را بکار برد. این مجموعه بهدست سرور مشخص میشود. سرور این مجموعه شناسه را با جای دادن دو عدد صحیح در بسته پذیرش (همان بستهای که سرور در آغاز کار در پاسخ به کلاینت برای ایجاد اتصال جدید، برای او میفرستد) مشخص میکند. کلاینت شناسههای خود را به گونهای از این مجموعه گزینش میکند که برخوردی پیش نیاید: در بین پنجرهها، پیکسمپها، فونتها، رنگنگاشتها و بافتهای گرافیکی، دو شی دارای شناسه یکسانی نباشند.
پس از اینکه یک منبع ساخته شد، کلاینت میتواند با شناسه آن منبع، از سرور درخواست کند که کاری را بر روی آن منبع انجام دهد. برخی از درخواستها، بر روی منبع تأثیرگذار هستند و ممکن است آن منبع را دگرگون کنند (برای نمونه، درخواست جابجا کردن یک پنجره)؛ برخی دیگر، اطلاعاتی که دربارهٔ یک منبع در سرور ذخیره شده را درخواست میدهند (همچون درخواست برای خصوصیات یک پنجره).
شناسهها نه تنها در کلاینت، بلکه در سرور هم یکتا و منحصربهفرد هستند. برای نمونه، دو پنجره گوناگون هیچگاه شناسه یکسانی ندارند، حتی اگر دو کلاینت گوناگون آنها را ساخته باشند. یک کلاینت میتواند با دادن شناسه هر شیئی، به آن دسترسی داشته باشد. یک کلاینت میتواند به اشیائی که دیگر کلاینتها ساختهاند هم دسترسی داشته باشد، حتی اگر شناسه آن شی، بیرون از بازهٔ شناسههای آن کلاینت باشد.
در نتیجه، دو کلاینت گوناگون که هر دو به یک سرور متصل هستند، میتوانند از یک شناسه مشترک برای دسترسی داشتن به یک شی یکسان استفاده کنند. برای نمونه اگر کلاینتی یک شی با شناسه 0x1e00021
ساخته باشد و این عدد 0x1e00021
را به یک برنامه دیگر هم بدهد (این کار میتواند به هر شکل دلخواهی انجام شود، همانند ذخیره کردن این عدد در یک فایل به گونهای که برنامه دیگر بتواند آن را از آن فایل بخواند)، برنامه دیگر هم میتواند تا بر روی همان پنجره کاری را انجام دهد. برای نمونه، برنامه گوستویو در سامانه پنجرهای اکس از این ویژگی اینگونه بهره میبرد: این برنامه یک زیرپنجره ساخته، سپس شناسه آن را در یک متغیر محیطی میگذارد، سپس برنامه گوستاسکریپت را فراخوانی میکند، سپس برنامه گوستاسکریپت، محتوای یک فایل پستاسکریپت را در این پنجره نمایش میدهد.[8]
معمولاً وقتی که یک کلاینت اتصالش را با سرور قطع میکند، منابع به وجود آمده بهدست آن کلاینت نابود میشوند. با این حال، یک کلاینت پیش از پایان دادن به اتصال، میتواند از سرور بخواهد که منابع را نابود نکند.
رویدادها
![Thumb](http://upload.wikimedia.org/wikipedia/fa/thumb/6/6c/Xevents_fa.svg/320px-Xevents_fa.svg.png)
رویدادها، بستههایی هستند که از سوی سرور برای کلاینت فرستاده میشوند، این بستهها کلاینت را از رخ دادن رویدادی که ممکن است برای کلاینت جالب توجه باشد، آگاه میکنند. برای نمونه، هنگامی که کاربر کلیدی را فشار میدهد یا بر روی دکمهای کلیک میکند، رویدادی برای کلاینت فرستاده میشود. رویدادها تنها برای ورودی گرفتن از کاربر و فعل و انفعالات او نیستند. برای نمونه، هنگامی که زیرپنجرهای در یک پنجره ساخته میشود، رویدادی برای آگاه کردن کلاینت از این رخداد، برای آن فرستاده میشود.
هر رویدادی با یک پنجره در ارتباط است. برای نمونه، اگر کاربر هنگامی که نشانگر ماوس بر روی یک پنجره قرار دارد، روی آن پنجره کلیک کند، رویداد با آن پنجره در ارتباط خواهد بود. بستهٔ رویدادی که برای کلاینت فرستاده میشود، شناسه آن پنجره را در بر دارد.
یک کلاینت میتواند از سرور بخواهد که رویدادی را برای یک کلاینت دیگر بفرستد؛ کلاینتها از این ویژگی برای برقراری ارتباط با یکدیگر استفاده میکنند. برای نمونه، هنگامی که کلاینتی از سرور درخواست میکند که متن انتخابشده بهدست کاربر برایش فرستاده شود، یک چنین رویدادی ساخته میشود (ممکن است کاربر متن موجود در پنجرهای که متعلق به یک کلاینت دیگر است را انتخاب کرده باشد)؛ این رویداد، برای کلاینتی فرستاده میشود که پنجره حاوی متن انتخابشده را اداره میکند.
هنگامی که محتویات بخشی از یک پنجره، نابود شده و سپس دوباره نمایان میشود، رویدادی به نام Expose
برای کلاینت فرستاده میشود. محتوای یک پنجره میتواند در برخی شرایط نابود شود. برای نمونه اگر یک پنجره، بر روی پنجره دیگری جای بگیرد و همه یا بخشی از آن را بپوشاند، محتوای پنجره پوشیده شده نابود خواهد شد. البته این هنگامی است که سرور انباره پشتیبان برای آن پنجره را نگهداری نکرده باشد. سرور تضمین نمیکند که حتماً یک انباره پشتیبان نگهداری میکند، اما تضمین میکند که هر گاه نیاز به ترسیم دوباره محتوای یک پنجره بود، رویدادی را برای کلاینت بفرستد.
بسیاری از رویدادها تنها هنگامی برای کلاینت فرستاده میشوند که کلاینت از پیش آمادگی خود را برای دریافت آنها اعلام کرده باشد و مایل به دریافت آن رویدادها بوده باشد. دلیل این کار این است که شاید تنها چند گونه رویداد خاص برای برخی از کلاینتها جالب توجه باشد و کلاینتها نخواهند به همه آنها پاسخ دهند. برای نمونه، یک کلاینت ممکن است تنها بخواهد از رویدادهای صفحهکلید آگاه شود و علاقهای به رویدادهای ماوس نداشته باشد. با این حال، رویدادهایی هستند که حتی اگر کلاینت از پیش آمادگی خود را برای دریافت آنها نشان نداده باشد، باز هم برای کلاینت فرستاده میشوند.
کلاینتها با تنظیم کردن یکی از خصوصیات پنجره، مشخص میکنند که علاقهمند به دریافت کردن چه رویدادهایی هستند. برای نمونه، برای ترسیم دوباره پنجرهای که محتوای آن نابود شده، کلاینت باید رویداد Expose
را دریافت و پذیرش کند (این رویداد برای همین کار در نظر گرفته شده و کلاینت را آگاه میکند که محتوای پنجره نیازمند ترسیم دوباره است). با این حال، این رویداد تنها هنگامی برای کلاینت فرستاده میشود که کلاینت از پیش اعلام کرده باشد که میخواهد آن را دریافت کند. این کار با تنظیم کردن خصوصیت ماسک رویداد پنجره، با یک مقدار مناسب انجام میشود.
کلاینتهای گوناگون میتوانند رویدادهای مرتبط با یک پنجره یکسان را دریافت کنند. آنها حتی میتوانند ماسک رویداد آن پنجره را به گونهٔ متفاوتی مقداردهی کنند و بدین گونه، هر کدام رویدادهای گوناگونی را دریافت کنند. برای نمونه، یک کلاینت شاید بخواهد تنها رویدادهای مرتبط با صفحهکلیدی که برای یک پنجره رخ میدهد را دریافت کند، در حالی که کلاینت دیگر دوست دارد تنها رویدادهای مرتبط با ماوس برای همان پنجره را دریافت کند. این کار برای این شدنی است که سرور برای هر پنجره، ماسک رویداد جداگانهای را به ازای هر کلاینت نگهداری میکند. با این حال، برخی از رویدادها تنها میتوانند در هر زمان بهدست یک کلاینت دریافت شوند و کلاینتهای دیگر نمیتوانند همزمان همان رویداد را دریافت کنند. این رویدادها، گزارشهایی را دربارهٔ کلیک کردن دکمههای ماوس و همچنین تغییرات مرتبط با مدیریت پنجره را میفرستند.
برنامه xev
رویدادهای مرتبط با یک پنجره را نمایش میدهد. دستور xev -id WID
همه رویدادهای ممکن برای پنجرهای با شناسه WID
را دریافت کرده و چاپ میکند.
نمونه
در ادامه نمونهای از چگونگی تعامل و برپایی ارتباط بین یک کلاینت و سرور را مرور میکنیم. در این نمونه، کلاینت یک پنجره میسازد که جعبهای سیاهرنگ در آن جای دارد، برنامه همین که یک کلید فشرده شد، خارج میشود. در این مثال، سرور هیچ پاسخی به سوی کلاینت نمیفرستد، چرا که درخواستهای کلاینت پاسخی را در پی ندارند. اما این درخواستها میتوانند باعث رخ دادن یک خطا شوند:
- کلاینت اتصال تازهای را با سرور ایجاد کرده و بسته آغازین را برای سرور میفرستد. این بسته اطلاعاتی همچون ترتیب بایت مورد استفاده کلاینت، نسخه پروتکل و ... را در خود دارد.
- سرور با فرستادن یک بسته مناسب برای کلاینت، اتصال را میپذیرد (در این مثال نیازی به اعتبارسنجی و احراز هویت نیست). این بسته دربرگیرنده شناسه پنجره ریشه (در اینجا
0x0000002b
) و بازهای از شناسههاست که کلاینت میتواند این شناسهها را برای نامگذاری کردن منابع و اشیاء بکار برد. - کلاینت درخواست میکند که یک بافت گرافیکی پیشفرض با شناسه
0x00200000
ساخته شود. (این درخواست، همانند درخواستهای دیگر این مثال، پاسخی را در بر ندارد). - کلاینت از سرور میخواهد که یک پنجره سطح بالا بسازد. (در این مثال، کلاینت شناسه پنجره ریشه که
0x0000002b
بود را به عنوان پنجره پدر مشخص میکند، شناسه خود پنجره سطح بالا را0x00200001
در نظر میگیرد، اندازه پنجره را ۲۰۰ در ۲۰۰ پیکسل مشخص میکند و از سرور میخواهد تا این پنجره را در مختصات (۱۰٫۱۰) رسم کند). - کلاینت از سرور میخواهد که یکی از خصوصیات پنجرهای با شناسه
0x00200001
را تغییر دهد، و مشخص میکند که دوست دارد رویدادهایKeyPress
وExpose
را دریافت کند. اگر این رویدادها رخ دادند، سرور با فرستادن یک بسته مناسب، کلاینت را آگاه میکند. - کلاینت از سرور میخواهد تا پنجرهای که شناسه آن
0x00200001
است بر روی صفحه نقش شود (بر روی صفحه نشان داده شود). - وقتی که پنجره بر روی صفحه نمایان شد و نیاز به ترسیم محتوای آن بود، سرور رویداد
Expose
را برای کلاینت میفرستد. - در پاسخ به این رویداد، کلاینت با فرستادن یک درخواست
PolyFillRectangle
از سرور میخواهد جعبهای بر روی پنجره رسم شود. شناسه این پنجره0x00200001
و شناسه بافت گرافیکی آن0x00200000
است.
اگر پنجره دیگری بر روی پنجره جای گیرد و دوباره از روی آن برداشته شود، با فرض اینکه انباره پشتیبان نگهداری نشده باشد:
- سرور یک رویداد
Expose
دیگر ارسال میکند تا به کلاینت بگوید که محتوای پنجره باید دوباره رسم شوند. - کلاینت دوباره درخواست
PolyFillRectangle
را برای سرور میفرستد.
اگر کلیدی فشرده شود:
- سرور یک رویداد
KeyPress
برای کلاینت میفرستد تا او را از فشردهشدن کلیدی آگاه کند. - کلاینت پاسخ مناسبی برای آن رویداد خواهد فرستاد. (در این مثال، به اجرای خودش خاتمه خواهد داد)
رنگها
در سطح پروتکل، رنگها به شکل اعداد صحیح ۳۲ بیتی بدون علامت نمایش مییابند که pixelvalue نامیده میشوند. عناصر زیر بر روی نمایش رنگها تأثیر دارند:
- عمق رنگ
- رنگنگاشت[و 18] که جدولی است که شدت رنگهای آبی، قرمز، سبز در آن مشخص میشود.
- گونه بصری[و 19] که مشخص میکند چگونه جدول رنگنگاشت باید برای نمایش رنگها مورد استفاده قرار گیرد.
در سادهترین حالت، رنگنگاشت جدولی است که هر سطر آن حاوی یک سهتایی آرجیبی است. یک pixelvalue به نام x، نشاندهنده رنگی است که در سطر xام جدول قرار گرفتهاست. اگر کلاینت قادر باشد مدخلهای رنگنگاشت را تغییر دهد، این بازنمایش جدید توسط کلاس بصری[و 20] PseudoColor
نشان داده میشود. کلاس StaticColor
هم کلاسی مشابه است، اما در این کلاس کلاینت نمیتواند مدخلهای رنگنگاشت را تغییر دهد.
حدود ۶ کلاس بصری وجود دارد که هر کدام از آنها روش متفاوتی را برای نمایش دادن سهتایی RGB در یک pixelvalue دارند. PseudoColor
و StaticColor
دو تا از این کلاسها هستند. GrayScale
و StaticGray
هم دو تای دیگر هستند فرق آنها در این است که این جدولها فقط میزان شدت رنگ قهوهای را نمایش میدهند.
دو کلاس بصری باقیمانده با کلاسهایی که در بالا معرفی شدند متفاوت هستند، چرا که آنها pixelvalueها را به سه قسمت تقسیم میکنند و برای تعیین کردن شدت رنگهای آبی، قرمز و سبز، از سه جدول مجزا برای هر کدام استفاده میکنند. بر طبق این نحوه نمایش رنگ، یک pixelvalue به صورت زیر به یک سهتایی RGB تبدیل میشود:
- pixelvalue به صورت دنبالهای از بیتها در نظر گرفته میشود.
- این دنباله به سه دسته تقسیم میشود.
- هر کدام از این سه دسته بیت، به صورت یک عدد صحیح درمیآید و سپس از این عدد صحیح به عنوان یک اندیس، برای پیدا کردن یک مقدار در یکی از آن سه جدول مجزا، مورد استفاده قرار میگیرد.
این سازوکار نیازمند آن است که رنگنگاشت از سه جدول مجزا تشکیل شده باشد و به ازای هر رنگ اولیه، یک جدول مجزا وجود داشته باشد. نتیجه این تبدیل، همچنان یک سهتایی از مقادیری است که مشخصکننده شدت رنگها هستند. کلاسهای بصری که برای نمایش این تبدیل جدید استفاده میشود DirectColor
و TrueColor
هستند و فرق آنها در این است که آیا کلاینت میتواند رنگنگاشتها را تغییر دهد یا خیر.
این شش سازوکار برای نمایش رنگها به وسیلهٔ pixelvalueها، همگی نیازمند پارامترهای بیشتری هستند تا بتوانند کار کنند. این پارامترها در یک گونه بصری گردآوری میشوند. یک گونه بصری، حاوی یک کلاس بصری و دیگر پارامترهای مورد نیاز برای نمایش رنگهاست. هر سرور یک دسته ثابت از گونههای بصری دارد که هر کدام شناسه عددی مخصوص به خود را دارند. این شناسهها اعداد صحیح ۳۲ بیتی بدون علامت هستند، اما الزاماً متفاوت با شناسه منابع یا اتمهای (بعدا تشریح میشود) دیگر نیستند و ممکن است با آنها همپوشانی داشته باشند.
وقتی که اتصال یک کلاینت توسط سرور پذیرفته میشود، بسته پذیرشی که از طرف سرور برای کلاینت ارسال میشود حاوی دنبالهای از بلاکهاست که هر کدام از این بلاکها، حاوی اطلاعاتی دربارهٔ یک صفحهنمایش هستند. بلاک متناظر با هر صفحهنمایش، حاوی فهرستی از بلاکهای دیگر است که هر کدام از این بلاکها، مربوط به عمق رنگ خاصی است که توسط آن صفحهنمایش پشتیبانی میشود. این فهرست، به ازای هر یک از عمق رنگهای مورد پشتیبانی، حاوی فهرستی از گونههای بصری است. در نتیجه، هر صفحه نمایش تعدادی عمق رنگ دارد که هر کدام از این عمق رنگها، دارای چند گونه بصری هستند. هر گونه بصری را میتوان برای چندین صفحهنمایش با عمقهای مختلف مورد استفاده قرار داد.
بسته پذیرش به ازای هر گونه بصری، هم حاوی شناسه آن گونه بصری هست و هم حاوی پارامترهای واقعی که در آن گونه بصری وجود دارد (کلاس بصری و موارد دیگر). کلاینتها این اطلاعات را در خود ذخیره میکنند، چرا که بعداً نمیتوانند آنها را درخواست دهد. علاوه بر آن، کلاینتها نمیتوانند گونههای بصری را تغییر داده یا گونههای بصری جدید ایجاد کنند. درخواستی که برای ایجاد کردن یک پنجره جدید برای سرور ارسال میشود، حاوی عمق و شناسه گونه بصریای است که باید برای نمایش دادن رنگها در آن پنجره، مورد استفاده قرار گیرد.
رنگنگاشتها بدون توجه به اینکه سختافزاری که صفحه نمایش را کنترل میکند (همانند کارت گرافیک) از یک پالت استفاده میکند یا نه، بکار برده میشوند. پالت هم جدولی است که برای نمایش دادن رنگها بکار برده میشود. حتی اگر سختافزار از یک پالت استفاده نکند، سرورهاباز هم از رنگنگاشتها استفاده میکنند. هنگامی که سختافزار از پالت بهره میبرد، میتوان تنها شمار محدودی از رنگنگاشتها را بکار گرفت. یک رنگنگاشت هنگامی به کار گرفته میشود که سختافزار بر طبق آن رنگها را نشان میدهد. یک کلاینت میتواند از سرور بخواهد که یک رنگنگاشت را بکار بگیرد. با این حال، این کار ممکن است نیازمند از کار انداختن رنگنگاشت دیگری باشد. این کار باعث میشود پنجرههایی که از آن رنگنگاشت از کار انداخته شدهاستفاده میکنند، با رنگهای مناسب خود نمایش نیابند که به این پدیده color flashing یا technicolor میگویند. این مشکل میتواند با استفاده از رنگنگاشتهای استاندارد رفع شود. رنگنگاشتهای استاندارد، رنگنگاشتهایی هستند که در آنها رابطهای از پیشتعیینشده بین pixelvalueها و رنگها وجود دارد. به لطف این خصیصه رنگنگاشتهای استاندارد، برنامههای مختلف میتوانند آنها را بکار گیرند.
بهوجود آوردن رنگنگاشتها در قرارداد ICCCM بحث شدهاست. رنگنگاشتهای استاندارد توسط ICCCM و اکسلیب تنظیم میشوند.
اتمها
اتمها اعداد ۳۲ بیتی هستند که رشتهها را نمایش میدهند. سازندگان پروتکل، اتمها را به این دلیل معرفی کردند، که اتمها رشتهها را به شکلی کوتاه و با اندازهای ثابت نمایش میدهند.[9] در حالی که یک رشته میتواند طول دلخواهی داشته باشد، یک اتم همیشه اندازه ثابت ۳۲ بیتی دارد. در مواردی که بستههایی با یک رشته یکسان باید به صورت چند باره فرستاده شود، میتوان با اتمها، از شبکه به گونه بهینهتر سود جست. بستههای نوع رویداد که اندازه ثابت ۳۲ بایتی دارند، میتوانند اتمها را در خود جای دهند، اما ممکن است یک رشته متنی به اندازهای بزرگ باشد که نتوان آن را در بستههای رویداد گنجاند.
به گونه دقیقتر میتوان گفت که اتمها، شناسههایی برای رشتههایی که در سرور ذخیره شدهاند، هستند. آنها همانند شناسههای منابع (پنجره، پیکسمپ و غیره) هستند. اما دو تفاوت با آنها دارند. یکی اینکه شناسه اتمها بهدست سرور گزیده میشود و کلاینت در گزینش آنها نقشی ندارد. به عبارتی دیگر، هنگامی که کلاینت درخواست ساختن یک اتم تازه را میدهد، تنها رشتهای که قرار است ذخیره شود را برای سرور میفرستد، نه شناسه آن اتم را. این شناسه را سرور گزینش کرده و به صورت یک پاسخ برای کلاینت میفرستد. دومین فرق مهم بین اتمها و منابع این است که اتمها با کلاینتها در ارتباط نیستند و به آنها وابسته نیستند. هنگامی که اتمها در سرور ساخته میشوند، تا هنگامی که سرور خاموش یا راهاندازی دوباره نشده، در همانجا باقی خواهند ماند (منابع به گونه پیشفرض چنین رفتاری ندارند و وابسته به کلاینت هستند).
از آنجا که اتمها یک نوع شناسه هستند، یکتا هم هستند. با این حال، یک اتم و شناسه یک منبع میتوانند با یکدیگر همپوشانی داشته باشند. رشتهای که به یک اتم داده شده، نام اتم نامیده میشود. پس از اینکه یک اتم ساخته شد، نام آن را نمیتوان تغییر داد و دو اتم هم نمیتوانند نام یکسانی داشته باشند. در نتیجه، معمولاً از نام یک اتم برای اشاره به آن اتم استفاده میشود. «اتم ABCD» به شکل دقیقتر یعنی «اتمی که رشته ABCD به آن اختصاص یافته است». یک کلاینت، هم میتواند از سرور درخواست کند که یک اتم تازه بسازد و هم میتواند با دادن یک رشته به سرور، شناسه اتم آن را دریافت کند. برخی از اتمها از قبل تعریف شده هستند. (سرور آنها را با یک شناسه و رشته معین از قبل تعریف کردهاست).
اتمها را میتوان برای اهداف گوناگونی بکار برد. یکی از رایجترین استفاده از اتمها، برقرار کردن ارتباط بین دو یا چند کلاینت است که همگی به یک سرور یکسان متصل شدهاند. آنها به همراه ویژگیهای پنجرهها استفاده میشوند که در ادامه تشریح میشود.
با استفاده از برنامه xlsatoms
میتوان فهرست همه اتمهای موجود در سرور را چاپ کرد. این برنامه برای هر اتم، شناسه آن (که یک عدد است) و نام آن (که یک رشته است) را چاپ میکند.
خصیصهها
هر پنجره، یک سری ویژگی[و 21] از پیش تعریف شده و یک سری خصیصه[و 22] دارد که همه آنها در سرور ذخیره میشوند و کلاینت میتواند برای دسترسی به آنها، درخواستی را برای سرور بفرستد. ویژگیها، اطلاعاتی دربارهٔ یک پنجره هستند، مانند اندازه، مکان، رنگ پسزمینه و دیگر جیزها. خصیصهها، اطلاعات دلخواهی هستند که به یک پنجره چسبیده میشوند. برخلاف ویژگیها، خصیصهها معنی خاصی در سطح پروتکل اکس ندارند. یک کلاینت میتواند هر گونه اطلاعات دلخواهی را در خصیصه یک پنجره ذخیره کند.
یک خصیصه با نام، نوع و مقدار آن شناخته میشود. خصیصهها همانند متغیرها در زبانهای برنامهنویسی دستوری هستند، که یک کلاینت میتواند خصیصه تازهای را با نام و نوع دلخواه ساخته و مقداری را در آن بگذارد. خصیصهها مخصوص همان پنجره هستند: دو خصیصه همنام میتواند در دو پنجره گوناگون وجود داشته باشد، در حالی که مقدار و نوع آنها با یکدیگر ناهمسان است.
نام، نوع و مقدار یک خصیصه به صورت رشته، یا به شکل دقیقتر، اتم هستند. رشتهها در سرور ذخیره شده و کلاینت میتواند با شناسهها به آنها دسترسی داشته باشد. یک کلاینت میتواند با شناسهٔ اتمی که دربرگیرنده نام یک خصیصه است، به آن خصیصه دسترسی داشته باشد.
خصیصهها بیشتر برای ارتباطات بین کلاینتی بکار برده میشوند. برای نمونه، یک خصیصه به نام WM_NAME
(این خصیصه توسط اتمی که رشته اختصاص یافته به آن "WM_NAME"
است نامگذاری شدهاست) هست که برای ذخیره کردن نام پنجرهها بکار برده میشود. مدیر پنجرهها معمولاً این خصیصه را میخوانند و سپس آن را در نوار عنوان پنجره نمایش میدهند.
برخی از انواع ارتباطات بین کلاینتی، از خصیصههای پنجره ریشه استفاده میکنند. برای نمونه، بر پایه مشخصاتی که فریدسکتاپ[10] برای مدیر پنجرهها تعریف کرده، مدیر پنجرهها باید شناسه پنجرهای که هماکنون فعال است و فوکوس را در اختیار دارد را در یکی از خصیصههای پنجره ریشه به نام _NET_ACTIVE_WINDOW
ذخیره کنند. منابع اکس که حاوی پارامترهای برنامهها هستند هم در خصیصههای پنجره ریشه ذخیره میشوند. به این گونه، همه کلاینتها میتوانند به این خصیصهها دسترسی داشته باشند، حتی اگر این کلاینتها بر روی رایانههای گوناگون اجرا شوند.
برنامه xprop
خصیصههای یک پنجره دلخواه را نمایش میدهد. دستور xprop -root
، نام، نوع و مقدار همه خصیصههای پنجره ریشه را چاپ میکند.
نگاشت کردن
![Thumb](http://upload.wikimedia.org/wikipedia/commons/1/1c/Akey.jpg)
در سامانه پنجرهای اکس، هر کلیدی که بر روی دستگاههای ورودی از جمله ماوس و کیبورد وجود دارد، یک عدد منحصربفرد مابین ۸ تا ۲۵۵ دارد که به آن keycode میگویند. یک keycode تنها یک کلید ویژه را شناسایی میکند، نه یک کاراکتر یا لفظ (مانند Page up) که بر روی کلید چاپ شدهاند را. درعوض هر کدام از این الفاظ یا کاراکترها با یک keysym شناسایی میشوند. درحالیکه keycode تنها به کلیدی که فشرده شدهاست وابسته است، یک keysym ممکن است به اینکه دکمه Shift یا یک اصلاحگر[و 23] دیگر هم فشرده شده باشد، بستگی داشته باشد.
هنگامی که کلیدی فشرده یا رها میشود، سرور رویدادهایی از نوع KeyPress
یا KeyRelease
را برای کلاینتهای مورد نظر میفرستد. این رویدادها دادههای زیر را در خود دارند:
- keycode کلیدی که فشرده شدهاست.
- وضعیت کنونی اصلاحگرها (شیفت، کنترل و ...) و دکمههای ماوس
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/b/b8/Xkeyboard.svg/640px-Xkeyboard.svg.png)
بنابراین سرور keycode و وضعیت اصلاحگرها را بدون اینکه تلاش کند خود آنها را به یک کاراکتر ویژه ترجمه کند، برای کلاینت میفرستد و وظیفه ترجمه و تفسیر آنها را بر دوش کلاینت واگذار میکند. برای نمونه، یک کلاینت ممکن است رویدادی مبنی بر اینکه یک کلید ویژه در حالی فشرده شدهاست که دکمه شیفت هم پایین نگه داشته شده، دریافت کند. اگر در حالت معمول این کلید خاص، کاراکتر 'a' را تولید میکرده، کلاینت (و نه سرور) این رویداد را به منزله وارد شدن کاراکتر 'A' تلقی میکند.
درحالیکه ترجمه keycodeها به keysym بهدست کلاینت انجام میشود، جدولی که ارتباط بین آنها را مشخص میکند در سرور نگهداری میشود. ذخیره کردن این جدول در سرور که یک جای عمومی و مرکزی است، این امکان را فراهم میکند تا همه کلاینتها بتوانند به آن دسترسی داشته باشند. کلاینتها تنها از سرور، نگاشت کردن keycodeها به keysymها را درخواست میکنند و از آن برای رمزگشایی کردن keycodeها و اصلاحگرها به یک keysym استفاده میکنند. با این حال، کلاینتها میتوانند این نگاشت کردن را به خواست خودشان تغییر دهند.
یک اصلاحگر کلیدی است که هنگامی فشرده میشود، چگونگی تفسیر شدن کلیدها را تغییر میدهد. یکی از اصلاحگرهای رایج، کلید شیفت است. وقتی کلیدی که در حالت معمول کاراکتر 'a' را تولید میکند، به همراه کلید شیفت فشرده میشود، باعث تولید شدن یک کاراکتر بزرگ 'A' میشود. دیگر اصلاحگرهای رایج، کلید آلت، کنترل و متا[و 24] هستند.
سرور اکس حداکثر با هشت عدد اصلاحگر کار میکند. ضمناً، هر اصلاحگر میتواند بیش از یک کلید داشته باشد. این کار بایسته است، چرا که بیشتر کیبوردها دو کلید برای برخی از اصلاحگرها دارند. برای نمونه، بیشتر کیبوردها دو کلید شیفت دارند (یکی در سمت چپ و دیگری در سمت راست). این دو کلید، در هنگام فشردهشدن هر کدام keycode ویژه و متفاوت از یکدیگری را تولید میکنند، اما سرور اکس هر دو آنها را به عنوان اصلاحگر شیفت میشناسد.
سرور اکس برای هر کدام از این هشت اصلاحگر، فهرستی از keycodeها را نگه میدارد که آنها را به عنوان آن اصلاحگر تفسیر میکند. برای نمونه، اگر در فهرست اولین اصلاحگر (اصلاحگر شیفت)، یک kecode با مقدار 0x37
وجود داشته باشد، آنگاه سرور کلیدی که باعث تولید شدن keycodeای با مقدار 0x37
میشود را به عنوان یک کلید شیفت در نظر میگیرد.
هرچند که فهرستهای مربوط به نگاشت کردن اصلاحگرها در سرور نگهداری میشود، اما هر کلاینتی میتواند آنها را به خواست خود تغییر دهد. برای نمونه، یک کلاینت میتواند درخواست دهد که کلید F1 به فهرست اصلاحگر شیفت افزوده شود. با این کار، کلید F1 همانند یک کلید شیفت کار میکند. با این حال، keycode اصلی متناظر با F1، همچنان در هنگام فشردهشدن این کلید تولید میشود. در نتیجه، F1 همانگونه کار میکند که پیش از آن کار میکرده (برای نمونه ممکن است یک پنجره Help در هنگام فشرده شدن F1 باز شود)، اما همچنین به عنوان یک کلید شیفت هم کار میکند (برای نمونه فشردن کلید 'a' به همراه F1 میتواند باعث تولید شدن یک کاراکتر 'A' در یک ویرایشگر متن شود).
سرور اکس همچنین سازوکار برای نگاشت کردن دکمههای ماوس دارد. با این حال، دکمههای ماوس تنها میتوانند با یکدیگر جایگذاری شوند. این کار به ویژه برای تعویض کردن دکمههای چپ و راست برای استفاده آسانتر توسط افراد راستدست و چپدست سودمند است.
قاپیدن رویدادها
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/7/72/Xgrab.svg/320px-Xgrab.svg.png)
قاپیدن رویدادها[و 25] وضعیتی است که در آن تمام رویدادهای مرتبط با کیبورد و ماوس، تنها برای یک کلاینت خاص ارسال میشود. به عبارت دیگر، یک کلاینت رویدادهایی که در اصل برای کلاینتهای دیگر هستند را از آنها میقاپد. یک کلاینت میتواند درخواست قاپیدن رویدادهای کیبورد، ماوس یا هر دو را از سرور درخواست کند. اگر سرور درخواست کلاینت را برآورده سازد، آنگاه تمام رویدادهای مرتبط با ماوس/کیبورد، برای آن کلاینت ارسال میشود؛ تا وقتی که کلاینت grab را رها کند. کلاینتهای دیگر این رویدادها را دریافت نخواهند کرد.
کلاینت در هنگام قاپیدن رویدادها، پنجره قاپیدن را هم مشخص میکند. در این حالت، تمام رویدادها طوری برای کلاینت ارسال میشوند که انگار مرتبط با آن پنجره هستند. با این حال دیگر کلاینتها هیچ رویدادی را دریافت نمیکنند، حتی اگر آن رویدادها را در پنجره قاپیدن انتخاب کرده باشند. دو نوع قاپیدن وجود دارد:
- اکتیو: قاپیدن رویدادها بلافاصله صورت میگیرد.
- پسیو: تنها زمانی صورت میگیرد که یک کلید خاص از کیبورد یا یک دکمه خاص از ماوس (که از قبل تعیین شده) فشرده شود و وقتی که کلید رها شد، قاپیدن رویدادها هم پایان مییابد.
کلاینتها میتوانند بر روی کیبورد، مکاننما، یا هر دو آنها درخواست قاپیدن رویدادها را بکنند. یک درخواست قاپیدن، ممکن است حاوی درخواستی برای فریز کردن[و 26] صفحهکلید یا مکاننما باشد. تفاوت گرب کردن (قاپیدن رویدادها) و فریز کردن در این است که در گرب، گیرندهٔ رویدادها تغییر میکند و رویدادها به کلاینتی غیر از کلاینت اصلیشان تحویل داده میشوند، در حالی که فریز کردن باعث میشود تا رویدادها به هیچ گیرندهای تحویل داده نشوند. وقتی که دستگاهی فریز میشود، رویدادهایی که آن دستگاه تولید میکند در یک صف ذخیره میشوند تا بعدها پس از اتمام شدن عمل فریز، به گیرنده تحویل داده شوند.
پارامتر دیگری هم در رابطه با رویدادهای مکاننما وجود دارد که در تحویل دادن رویدادها مؤثر است: ماسک رویداد، که مشخص میکند چه نوع رویدادهایی باید تحویل داده شوند و از چه نوع رویدادهایی باید صرف نظر شود.
دیگر موارد
رویدادها و درخواستهای دیگری هم در پروتکل وجود دارد. برخی از درخواستها، در مورد رابطهٔ پدری بین پنجرهها هستند. یک کلاینت میتواند درخواست کند تا پدر یک پنجره تغییر یابد. یا میتواند اطلاعاتی را در مورد پدر یک پنجره درخواست کند. برخی دیگر از درخواستها، دربارهٔ انتخابها[و 27] هستند، با این حال، بیشتر این درخواستها بهدست پروتکلهای دیگری جز پروتکل اصلی تعریف و مشخص میشوند. دسته دیگر از درخواستها، درخواستهای مرتبط با فوکوس ورودی و شکل مکاننما هستند. همچنین یک کلاینت میتواند درخواست دهد مالک یک منبع (پنجره، pixmap و ...)، از بین برود که خود باعث از بین رفتن ارتباط سرور با آن میشود. در نهایت، یک کلاینت میتواند یک درخواست از نوع بدون عملیات را برای سرور بفرستد.
اضافات و افزونهها
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Oclock.png/220px-Oclock.png)
پروتکل سامانه پنجرهای اکس به گونه گسترشپذیر ساخته شدهاست. این پروتکل سازوکاری را فراهم میکند که یک کلاینت به کمک آن میتواند از وجود داشتن یک افزونه مطمئن شود. همچنین پروتکل اصلی، چگونگی ساخته شدن بستههای درخواست، رویداد و خطایی که متعلق به یک افزونه هستند را هم مشخص میکند.
یک کلاینت میتواند برای دادههایی که وابسته و مرتبط به یک افزونه دلخواه هستند، فهرست همه افزونههای موجود را درخواست کند. بستههایی که متعلق به یک افزونه هستند، مشابه همان بستههای اصلی پروتکل هستند. پروتکل اصلی، مشخص میکند که بستههای نوع درخواست، رویداد یا خطا، باید دربرگیرنده یک عدد صحیح باشند که این عدد صحیح، نوع آن بسته را مشخص میکند (برای نمونه، درخواستهایی که برای ساختن یک پنجره تازه بکار میروند، با عدد ۱ شمارهگذاری میشوند). بازهای از این اعداد صحیح برای افزونهها رزرو شدهاست.
اعتبارسنجی و تأیید هویت
در ابتدا، وقتی که کلاینت میخواهد ارتباطی را با سرور برقرار کند، سرور میتواند ارتباط را بپذیرد، آن را رد کند، یا کلاینت را اعتبارسنجی کند و در صورت تأیید شدن هویت کلاینت، ارتباط با آن را بپذیرد. روشهای گوناگونی برای اعتبارسنجی هست. یک درخواست اعتبارسنجی، روشی که باید برای اعتبارسنجی بکار برده شود را در خود دارد. پروتکل، مراحل انجام اعتبارسنجی را مشخص و تعریف نمیکند، چرا که مراحل اعتبارسنجی بستگی به روشی دارد که برای اعتبارسنجی بکار برده میشود، پروتکل تنها مشخص میکند که این فرایند، یا با فرستادن بسته پذیرش یا با فرستادن بسته عدم پذیرش از سوی سرور، پایان مییابد.
در طول یک فعل و انفعال عادی بین یک کلاینت و سرور، تنها درخواستهایی که با اعتبارسنجی در ارتباط هستند، در مورد روش دسترسی مبتنی بر میزبان[و 28] هستند. بهطور دقیقتر، یک کلاینت میتواند از سرور بخواهد که این روش فعال باشد یا نه، و همینطور میتواند از سرور بخواهد که فهرستی از میزبانهایی (کلاینتهایی) که مجاز به برقراری ارتباط هستند را بخواند یا تغییر دهد. برنامههای عادی از اینگونه درخواستها استفاده نمیکنند، این درخواستها توسط برنامه xhost
استفاده میشوند. این برنامه از این درخواستها به این منظور استفاده میکند تا به یک کاربر یا یک اسکریپت، اجازه دسترسی داشتن به سرور اکس را بدهد.
اکسلیب و دیگر کتابخانههای مرتبط
بیشتر برنامههای کلاینت با استفاده از کتابخانه اکسلیب با سرور ارتباط برقرار میکنند. در واقع، عمده کلاینتها از کتابخانههای جیتیکی، کیوت، موتیف و ... استفاده میکنند که این کتابخانهها خود در واقع در سطوح پایینتر از اکسلیب برای برقراری ارتباط با سرور استفاده میکنند. استفاده از اکسلیب اثرات زیر را بهدنبال دارد:
- اکسلیب کلاینت را نسبت به پاسخها و رویدادها همگام میکند:
- توابعی که در اکسلیب، درخواستی به طرف سرور ارسال میکنند، تا زمانی که پاسخ مناسب از طرف سرور برسد، بلوکه میشوند. به عبارت دیگر، کلاینتی که از اکسلیب استفاده نمیکند میتواند درخواستی را ارسال کند و سپس به انجام کارهای دیگری بپردازد تا وقتی که پاسخ درخواست را از سرور دریافت کند. اما کلاینتی که از اکسلیب استفاده میکند تنها میتواند درخواستی را برای سرور ارسال کند و منتظر رسیدن پاسخ آن درخواست بماند و از این رو کلاینتی که منتظر رسیدن پاسخ درخواستش است، بلوکه میشود (مگر اینکه کلاینت قبل از فراخوانی تابع، یک ریسه جدید را اجرا کرده باشد)
- چون سرور رویدادها را به صورت ناهمگام ارسال میکند، اکسلیب رویدادهای دریافت شده توسط کلاینت را در یک صف ذخیره میکند. کلاینت تنها میتواند با فراخوانی کردن صریح توابعی خاص در اکسلیب به این رویدادهای موجود در صف دسترسی داشته باشد. به عبارت دیگر، اگر کلاینت منتظر یک رویداد باشد، مجبور به بلوکه شدن یا کشیدن انتظار مشغول میشود.
- اکسلیب درخواستها را بلافاصله برای سرور ارسال نمیکند، ابتدا آنها را در یک صف ذخیره میکند که به آن بافر خروجی[و 29] میگویند، سپس در یکی از حالات زیر درخواستهای موجود در این بافر ارسال میشود:
- برنامه با فراخوانی کردن یک تابع خاص به نام
XFlush
صریحاً از اکسلیب بخواهد که این کار را انجام دهد. - برنامه تابعی مانند
XGetWindowAttributes
را فراخوانی کند که سرور در نتیجه فراخوانی این تابع، پاسخی را ارسال کند. - برنامه رویدادی را از صف رویدادها درخواست دهد (برای مثال با
XNextEvent
) و آن فراخوانی مسدود شود (برای مثال اگر صف خالی باشدXNextEvent
مسدود میشود)
- برنامه با فراخوانی کردن یک تابع خاص به نام
کتابخانههای سطح بالاتر همانند Xt (که موتیف و Xaw آن را بکار میبرند)، به برنامههای کلاینت اجازه میدهد تا برای برخی از رویدادها، توابع بازفراخوانی[و 30] را در نظر بگیرند. این کتابخانه به صف رویدادها سرکشی میکند و در هنگام نیاز، توابع منظور شده را اجرا میکند. برخی از رویدادها، همانند رویدادهایی که نیازمند ترسیم دوباره یک پنجره هستند، به گونه توکار بهدست Xt مدیریت میشوند.
کتابخانههای سطح پایین همانند XCB، دسترسی ناهمگام به پروتکل را شدنی میسازند، که باعث میشود تأخیر زمانی پنهان بماند.
بخشهای تشریحنشده
پروتکل اصلی سامانه پنجرهای اکس در مورد ارتباطات بین کلاینتی حکم نمیکند و مشخص نمیکند که برای ساختن عناصر دیداری رایج در واسطهای گرافیکی کاربر (دکمهها، منوها و ...)، چگونه باید پنجرهها را بکار برد. این عناصر با کتابخانههای سمت کلاینت مشخص و تعریف میشوند. ارتباطات بین کلاینتی در استانداردهای دیگری مانند ICCCM و مشخصههای freedesktop پوشش داده میشود.[10]
ارتباطات بین کلاینتی با سلکشنها، کات بافرها، و عمل drag-and-drop انجام میشود. این موارد، روشهایی هستند که یک کاربر میتواند آنها را برای جابجا کردن دادهها از یک کلاینت به کلاینت دیگر بکار برد. از آنجا که پنجرهها ممکن است بهدست برنامههای گوناگونی کنترل شوند، پروتکلی برای جابجایی این دادهها نیاز هست تا هماهنگی و ارتباط بین برنامهها ساماندهی. ارتباطات بین کلاینتی همچنین با مدیر پنجرههای اکس هم در ارتباط است. مدیر پنجرهها برنامههایی هستند که ظاهر پنجرهها و نما و حس کلی رابط کاربری را کنترل میکنند. مبحث مرتبط دیگر در ارتباطات بین کلاینتی، مبحث مدیریت جلسه یا مدیریت نشست است.
چگونگی آغاز یک نشست کاربری، مسئله دیگری است که در پروتکل اصلی در مورد آن بحث نشدهاست. عموماً این کار به گونه خودکار بهدست مدیر نشست اکس اداره میشود. با این حال کاربر میتواند به گونه دستی هم نشستی را با اجرا کردن برنامههای startx
و xinit
آغاز نماید.
انتقادها
معماری اکس بهگونهای است که کلاینت و سرور دو موجودیت جداگانه هستند که با شبکه با هم ارتباط برقرار میکنند، حتی اگر هر دو بر روی یک رایانه یکتا اجرا شوند. اطلاعات باید در یک سو بستهبندی شده، بر روی کانال مخابراتی فرستاده و سپس در سوی دیگر، از حالت بستهبندی بیرون آورده شود. این کار سربار اضافهای بر روی سیستم تحمیل میکند.[11]
به گونه پیشفرض، کلیه اطلاعات بهصورت رمزنگارینشده بر روی شبکه جابجا میشوند که یک مهاجم میتواند با شنود کردن کانال مخابرهای بین سرور و کلاینت، اطلاعات را کشف و ضبط کند.[12] یک راه حل رایج برای حل این مشکل، برقرار کردن یک تونل پوسته امن بین کلاینت و سرور است.
پروتکل اکس به گونه ناهمگام طراحی شدهاست که این مسئله میتواند در برخی موارد منجر به به وجود آمدن شرایط رقابتی در بخشهای گوناگون سیستم شود.[11]
نداشتن رهنمود در مورد چگونگی طراحی رابط کاربری باعث به وجود آمدن رابطهای ناسازگار شدهاست. اکس به خاطر طراحی پیچیده آن مورد انتقاد قرار گرفتهاست و همچنین برنامههای کاربردی ناچار هستند تا با پیچیدگیهای سطح پایین سختافزاری سروکار داشته باشند.[12]
واژهنامه
- asynchronously
- request
- reply
- event
- error
- client-server
- top-level window
- parent window
- sub-window
- backing store
- Re-parenting
- pixmap
- drawable
- Graphic context
- font server
- unload
- resource
- colormap
- visual type
- visual class
- Attribute
- property
- modifier
- Meta
- Grab
- freezing
- Selections
- host-based access method
- output buffer
- callback
منابع
پیوند به بیرون
Wikiwand in your browser!
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.