2012-01-30 16 views
13

मैं इस मामले में एक लिनक्स एप्लिकेशन - एक स्क्रीनसेवर बनाने की कोशिश कर रहा हूं - और यह को साबित कर रहा है कि विंडो पूर्ण स्क्रीन बनाने के सरल कार्य पर जानकारी प्राप्त करना मुश्किल हो। यहां तक ​​कि मौजूदा स्क्रीनसेवर का कोड इस बात का कोई जिक्र नहीं करता है कि वे इसे कैसे प्रबंधित करते हैं, और मुझे अभी तक XRemoveDecoration() जैसे कोई स्पष्ट कार्य नहीं दिख रहा है।एक्स 11/जीएलएक्स - फुलस्क्रीन मोड?

बहुत चारों ओर fumbling के बाद, मैं इस के साथ, एक विंडो डेस्कटॉप के रूप में एक ही आकार बनाने का प्रबंधन कैसे किया:

Window win = DefaultRootWindow(disp); 
XWindowAttributes getWinAttr; 
XGetWindowAttributes(disp, win, &getWinAttr); 
win = XCreateWindow(disp, win, 0, 0, getWinAttr.width, getWinAttr.height, 0, vInfo->depth, InputOutput, vInfo->visual, CWBorderPixel|CWColormap|CWEventMask|CWOverrideRedirect, &winAttr); 

लेकिन वह कुछ नहीं करता शीर्षक पट्टी और सीमाओं से छुटकारा पाने के। मुझे पता है कि एक रास्ता है, जाहिर है - लेकिन मुझे अभी तक उस दिशा में इशारा करने के लिए कुछ भी नहीं मिला है जो शीर्ष पर फेंकने वाली किसी अन्य विशाल पुस्तकालय पर भरोसा नहीं करता है (जो मौजूदा स्क्रीनसेवर निश्चित रूप से उपयोग नहीं कर रहे हैं)।

संपादित करें: कृपया मेरी पोस्ट से जानकारी न हटाएं। एक बहुत अच्छा कारण है कि मैंने स्पष्ट रूप से बताया कि मौजूदा स्क्रीनसेवर वैकल्पिक पुस्तकालयों का उपयोग नहीं कर रहे हैं, और ऐसा इसलिए है क्योंकि मैं पिछले दिनों के लिए स्रोत कोड का विश्लेषण कर रहा हूं।

मैंने उस उत्तर का चयन किया है जो सबसे अधिक सीधे प्रश्न का उत्तर देता है, और सामान्य रूप से आवेदन पर लागू होता है।

यदि आपको यह प्रश्न xscreensavers शोध करने में मिला है ... वही अभी भी लागू होता है। हां, xscreensaver का अपना एपीआई है - जो जटिल है, और वास्तव में कोड की अधिक पंक्तियां लिखना शामिल है (हां, गंभीरता से)। यदि आप अपने स्क्रीनसेवर में ओपनजीएल चाहते हैं, तो आपको एपीआई (xlockmore, एक प्रतिस्पर्धी प्रणाली) और एक संगतता परत से गुजरना होगा जो इसे xscreensaver में अनुवाद करता है।

हालांकि, xscreensaver किसी भी प्रोग्राम चलाने में सक्षम है जो वर्चुअल रूट विंडो (vroot.h में देखें) स्क्रीनसेवर के रूप में उपयोग कर सकता है। तो मेरी सलाह है कि बस ऐसा करें - आपके पास अधिक नियंत्रण होगा, कोई सीमित API नहीं होगा, और अधिक पोर्टेबिलिटी होगी। (एक उदाहरण मैं को देखा भी, लिनक्स या विंडोज के लिए संकलन कर सकते हैं एक ही फाइल के साथ!)

+2

+1। – Flexo

उत्तर

10

एक तरीका यह विंडो प्रबंधक बायपास करने के लिए है:

XSetWindowAttributes wa;              
wa.override_redirect = True;           
XCreateWindow(..., &wa); 
+0

आप मुख्य कार्यक्रम प्राप्त करने के लिए इसके साथ ग्रैबकीबोर्ड चाहते हैं। – eile

+3

वह ... वास्तव में काम करता है। अपने चरणों का पता लगाने की कोशिश कर रहा है, मुझे अभी भी उस टॉगल के उपयोग से संबंधित कोई संसाधन नहीं मिला है, और एक्स स्क्रीनसेवर में से कोई भी ऐसा प्रतीत नहीं होता है ... लेकिन जोव द्वारा, यह वास्तव में काम करता है! – DigitalMan

1

मैंने पाया freeglut फुलस्क्रीन अच्छी तरह से काम करता है, तब भी जब होस्टिंग अंदर शेडर आधारित opengl आवेदन। यहां आंतरिक कोड जिसे कॉल किया जाता है (एक्स 11 शाखा ...)। HTH

#define _NET_WM_STATE_TOGGLE 2 
static int fghResizeFullscrToggle(void) 
{ 
    XWindowAttributes attributes; 

    if(glutGet(GLUT_FULL_SCREEN)) { 
     /* restore original window size */ 
     SFG_Window *win = fgStructure.CurrentWindow; 
     fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE; 
     fgStructure.CurrentWindow->State.Width = win->State.OldWidth; 
     fgStructure.CurrentWindow->State.Height = win->State.OldHeight; 

    } else { 
     /* resize the window to cover the entire screen */ 
     XGetWindowAttributes(fgDisplay.Display, 
       fgStructure.CurrentWindow->Window.Handle, 
       &attributes); 

     /* 
     * The "x" and "y" members of "attributes" are the window's coordinates 
     * relative to its parent, i.e. to the decoration window. 
     */ 
     XMoveResizeWindow(fgDisplay.Display, 
       fgStructure.CurrentWindow->Window.Handle, 
       -attributes.x, 
       -attributes.y, 
       fgDisplay.ScreenWidth, 
       fgDisplay.ScreenHeight); 
    } 
    return 0; 
} 

static int fghEwmhFullscrToggle(void) 
{ 
    XEvent xev; 
    long evmask = SubstructureRedirectMask | SubstructureNotifyMask; 

    if(!fgDisplay.State || !fgDisplay.StateFullScreen) { 
     return -1; 
    } 

    xev.type = ClientMessage; 
    xev.xclient.window = fgStructure.CurrentWindow->Window.Handle; 
    xev.xclient.message_type = fgDisplay.State; 
    xev.xclient.format = 32; 
    xev.xclient.data.l[0] = _NET_WM_STATE_TOGGLE; 
    xev.xclient.data.l[1] = fgDisplay.StateFullScreen; 
    xev.xclient.data.l[2] = 0; /* no second property to toggle */ 
    xev.xclient.data.l[3] = 1; /* source indication: application */ 
    xev.xclient.data.l[4] = 0; /* unused */ 

    if(!XSendEvent(fgDisplay.Display, fgDisplay.RootWindow, 0, evmask, &xev)) { 
     return -1; 
    } 
    return 0; 
} 

static int fghToggleFullscreen(void) 
{ 
    /* first try the EWMH (_NET_WM_STATE) method ... */ 
    if(fghEwmhFullscrToggle() != -1) { 
     return 0; 
    } 

    /* fall back to resizing the window */ 
    if(fghResizeFullscrToggle() != -1) { 
     return 0; 
    } 
    return -1; 
} 


#endif /* TARGET_HOST_POSIX_X11 */ 
1

कोशिश एक उदाहरण के लिए इस पर देख रहे हैं:

सच स्लिक स्क्रीनसेवर पोर्ट CreateWindow() driver.c में समारोह में http://rss-glx.sourceforge.net/

देखो GLX करने के लिए।

+0

दुर्भाग्यवश, यह मैंने जो कोशिश की है उससे बहुत अलग नहीं लगता है (और काम करने के लिए समाप्त होने वाले ओवरराइड_रेडरेक्ट की कमी है), और किसी भी तरह से सामान्य से क्या चल रहा है पर भी कम टिप्पणी होती है। – DigitalMan

+0

@DigitalMan INSTALL.xscreensaver पढ़ें। इस FAQ को भी जांचें http://www.jwz.org/xscreensaver/faq.html#popup- विन्डोज़। डेटनवॉल्फ की तरह पोस्ट किया गया यह लगता है कि आप स्क्रीन सेवर डेमॉन में प्लग करने के बजाय अपना स्वयं का पूर्ण स्क्रीन एप्लिकेशन बना रहे हैं। – Fred

1

यह बिल्कुल मुश्किल नहीं है। here वर्णित अनुसार आपको सही सूची में दायां परमाणु जोड़ना होगा।

2

आपके पास मौजूद जानकारी का टुकड़ा यह है कि स्क्रीनसेवर पूर्णस्क्रीन जाने के लिए ज़िम्मेदार नहीं हैं। स्क्रीनसेवर डिमन स्क्रीनसेवर विंडो का प्रबंधन करेगा, इसे समर्पित स्क्रीनसेवर विंडो परत में रखेगा और इसे पूर्ण स्क्रीन बना देगा।

तो एक स्क्रीनसेवर लिखने के लिए आप स्पष्ट हैं।यदि आप एक पूर्णस्क्रीन गेम लिखने के बारे में थे, तो आपको विंडो को WM द्वारा प्रबंधित करने से रोकने के लिए ओवरराइड रीडायरेक्ट विशेषता सेट करना होगा और इसे पूरी स्क्रीन को कवर करना होगा।

+0

यह डिफ़ॉल्ट xscreensaver मॉड्यूल में मामला प्रतीत होता है, हां, लेकिन ओपनजीएल एड-ऑन सार्वभौमिक रूप से अपनी खिड़कियां बना रहे हैं। – DigitalMan

+0

@DigitalMan: विंडो निर्माण! = विंडो प्रबंधन। प्रभावी रूप से xscreensaver डेमॉन विंडो प्रबंधक की तरह कार्य करता है, लेकिन केवल स्क्रीनसेवर विंडो के लिए। एक्स-स्क्रीनसेवर एक्सटेंशन एक अतिरिक्त प्रकार की रूट विंडो घोषित करता है, जो हमेशा अन्य सभी विंडोज़ के शीर्ष पर होता है और स्क्रीनसेवर डिमन प्रभाव कार्यक्रम की खिड़की को स्थानांतरित करने के लिए ज़िम्मेदार होता है। – datenwolf

1

आईसीसीसीएम विशिष्टता atom का उपयोग करने का सबसे अच्छा और आसान तरीका यह है कि सबसे हालिया विंडो प्रबंधक के लिए काम करेगा। बस निम्नलिखित कोड का उपयोग करें:

Atom wm_state = XInternAtom (display, "_NET_WM_STATE", true); 
Atom wm_fullscreen = XInternAtom (display, "_NET_WM_STATE_FULLSCREEN", true); 

XChangeProperty(display, window, wm_state, XA_ATOM, 32, 
       PropModeReplace, (unsigned char *)&wm_fullscreen, 1); 

आपका खिड़की, पारदर्शी हो सकता है यदि ऐसा है तो, बस XSetBackground() समारोह जहां आपको उसकी आवश्यकता का उपयोग करें और यह किया है। स्पष्ट रूप से कुछ शोध करने के लिए

संबंधित मुद्दे