plugin-support.cpp
上传用户:hongyu5696
上传日期:2018-01-22
资源大小:391k
文件大小:17k
源码类别:

PlugIns编程

开发平台:

Unix_Linux

  1. #include "plugin.h"
  2. #include <strings.h>
  3. #include <errno.h>
  4. #include <sys/wait.h>
  5. extern int errno;
  6. extern int DEBUG;
  7. void lowercase(char string[])
  8. {
  9.     int i = 0;
  10.     if (DEBUG > 1)
  11. printf("in lowercasen");
  12.     while (string[i]) {
  13. string[i] = tolower(string[i]);
  14. i++;
  15.     }
  16.     return;
  17. }
  18. void unEscapeXML(char *string)
  19. {
  20.     char *p;
  21.     if (DEBUG > 1)
  22. printf("in unHTMLn");
  23.     while ((p = strstr(string,"&amp;")) != NULL) {
  24.      strcpy( p + 1, p + 5);
  25.     }
  26.     return;
  27. }
  28. int fexists(char *file)
  29. {
  30.     FILE *fp;
  31.     if (DEBUG > 1)
  32. printf("in fexistsn");
  33.     if (file == NULL)
  34. return 0;
  35.     fp = fopen(file, "r");
  36.     if (fp != NULL) {
  37. fclose(fp);
  38. return 1;
  39.     } else {
  40. return 0;
  41.     }
  42. }
  43. char *getURLHostname(char *url)
  44. {
  45.     char *hostname;
  46.     char *loc;
  47.     int i, len;
  48.     if (DEBUG > 1)
  49. printf("entering getURLHostnamen");
  50.     if (url == NULL)
  51. return NULL;
  52.     len = strlen(url);
  53.     if (len == 0)
  54. return NULL;
  55.     hostname = (char *) NPN_MemAlloc(sizeof(char) * (len + 1));
  56.     strcpy(hostname, url);
  57.     loc = strstr(url, "://");
  58.     if (loc == NULL) {
  59. NPN_MemFree(hostname);
  60. return NULL;
  61.     }
  62.     loc = loc + 3;
  63.     i = 0;
  64.     while (loc[0] != '/') {
  65. hostname[i] = loc[0];
  66. loc++;
  67. i++;
  68. if (i > len) {
  69.     i = 0;
  70.     break;
  71. }
  72.     }
  73.     if (i == 0) {
  74. NPN_MemFree(hostname);
  75. hostname = NULL;
  76.     } else {
  77. hostname[i] = '';
  78.     }
  79.     if (DEBUG > 1)
  80. printf("exiting getURLHostname with %sn", hostname);
  81.     return hostname;
  82. }
  83. char *getURLFilename(const char *url)
  84. {
  85.     char *filename;
  86.     char *tmp;
  87.     int len;
  88.     if (DEBUG > 1)
  89. printf("in getURLFilenamen");
  90.     if (url == NULL)
  91. return NULL;
  92.     len = strlen(url);
  93.     if (len == 0)
  94. return NULL;
  95.     filename = (char *) NPN_MemAlloc(sizeof(char) * (len + 1));
  96.     tmp = rindex(url, '/');
  97.     if (tmp == NULL) {
  98. strcpy(filename, url);
  99. return filename;
  100.     }
  101.     strcpy(filename, tmp + 1); // take everything upto, but not including the / starting from the right.
  102.     return filename;
  103. }
  104. char *getURLBase(char *url)
  105. {
  106.     char *base;
  107.     int i, len;
  108.     if (DEBUG > 1)
  109. printf("in getURLBasen");
  110.     if (url == NULL)
  111. return NULL;
  112.     len = strlen(url);
  113.     if (len == 0)
  114. return NULL;
  115.     base = (char *) NPN_MemAlloc(sizeof(char) * (len + 1));
  116.     strcpy(base, url);
  117.     if (DEBUG > 1)
  118. printf("in getURLBase base: %sn", base);
  119.     for (i = len - 1; i >= 0; i--) {
  120. if (base[i] != '/') {
  121.     base[i] = '';
  122. } else {
  123.     break;
  124. }
  125.     }
  126.     if ((strlen(base) == 0) || (i <= 0)) {
  127. NPN_MemFree(base);
  128. base = NULL;
  129.     }
  130.     if (base != NULL) {
  131. if (DEBUG)
  132.     printf("exiting URL base with %sn", base);
  133.     } else {
  134. if (DEBUG)
  135.     printf("exiting URL base with NULLn");
  136.     }
  137.     return base;
  138. }
  139. int isMms(char *url, int nomediacache)
  140. {
  141.     if (url == NULL)
  142. return 0;
  143.     if ((strncasecmp(url, "mms://", 6) == 0)
  144. || (strncasecmp(url, "mmst://", 7) == 0)
  145. || (strncasecmp(url, "mmsu://", 7) == 0)
  146. || (strncasecmp(url, "dvd://", 6) == 0)
  147. || (strncasecmp(url, "smb://", 6) == 0)
  148. || (strncasecmp(url, "rtsp://", 7) == 0)) {
  149. if (DEBUG > 1)
  150.     printf("isMms = truen");
  151. return 1;
  152.     } else {
  153. if (nomediacache) {
  154.     if ((strncasecmp(url, "file://", 7) == 0)
  155. || (strncasecmp(url, "smb://", 6) == 0)
  156. || fexists(url)) {
  157. if (DEBUG > 1)
  158.     printf("isMms = falsenurl = %sn", url);
  159. return 0;
  160.     } else {
  161. if (DEBUG > 1)
  162.     printf("isMms = truen");
  163. return 1;
  164.     }
  165. } else {
  166.     if (DEBUG > 1)
  167. printf("isMms = falsenurl = %sn", url);
  168.     return 0;
  169. }
  170.     }
  171. }
  172. void mmsToHttp(char *dest, char *src)
  173. {
  174.     char *temp;
  175.     if (strncasecmp(src, "mms", 3) == 0) {
  176. temp = (char *) NPN_MemAlloc(sizeof(char) * (strlen(src) + 1 +
  177.      sizeof("http") -
  178.      sizeof("mms")));
  179. strcpy(temp, "http");
  180. strcat(temp, src + 3);
  181. strcpy(dest, temp);
  182. NPN_MemFree(temp);
  183.     }
  184.     return;
  185. }
  186. int URLcmp(const char *url1, const char *url2)
  187. {
  188.     char *buffer1, *buffer2;
  189.     char *tmp1;
  190.     char *tmp2;
  191.     char *q1; // question mark in tmp
  192.     char *q2; // question mark in tmp2
  193.     int tmp1hasq = 0; // tmp1 has a ?
  194.     int tmp2hasq = 0; // tmp2 has a ?
  195.     char *hostname1 = NULL; // hostname1
  196.     char *hostname2 = NULL; // hostname2
  197.     char *protocol1 = NULL;
  198.     char *protocol2 = NULL;
  199.     int ret;
  200.     if (DEBUG > 1)
  201. printf("in URLcmpn");
  202.     if (strcmp(url1, url2) == 0)
  203. return 0;
  204.     // replace %20 with spaces in both strings
  205.     buffer1 = strdup(url1);
  206.     buffer2 = strdup(url2);
  207.     while ((tmp1 = strstr(buffer1, "%20"))) {
  208. if (tmp1 != NULL) {
  209.     *tmp1 = ' ';
  210.     tmp1++;
  211.     *tmp1 = '';
  212.     strcat(buffer1, tmp1 + 2);
  213. }
  214.     }
  215.     while ((tmp1 = strstr(buffer2, "%20"))) {
  216. if (tmp1 != NULL) {
  217.     *tmp1 = ' ';
  218.     tmp1++;
  219.     *tmp1 = '';
  220.     strcat(buffer2, tmp1 + 2);
  221. }
  222.     }
  223.     if (strcmp(buffer1, buffer2) == 0) {
  224. //if (DEBUG) printf("URL's matchn buffer1 %s len:%in buffer2 %s len %in",buffer1,strlen(buffer1),buffer2,strlen(buffer2));
  225. free(buffer1);
  226. free(buffer2);
  227. ret = 0;
  228.     } else {
  229. //if (DEBUG) printf("URL's don't matchn buffer1 %s len:%in buffer2 %s len%in",buffer1,strlen(buffer1),buffer2,strlen(buffer2));
  230. ret = -1;
  231.     }
  232.     if (strncasecmp(buffer1, "file://", 7) == 0) {
  233. if (strcmp(buffer1 + 7, buffer2) == 0) {
  234.     free(buffer1);
  235.     free(buffer2);
  236.     ret = 0;
  237. }
  238.     }
  239.     if (strncasecmp(buffer2, "file://", 7) == 0) {
  240. if (strcmp(buffer1, buffer2 + 7) == 0) {
  241.     free(buffer1);
  242.     free(buffer2);
  243.     ret = 0;
  244. }
  245.     }
  246.     if (ret == -1) {
  247. hostname1 = getURLHostname(buffer1);
  248. hostname2 = getURLHostname(buffer2);
  249. if (hostname1 != NULL && hostname2 != NULL
  250.     && strstr(hostname2, hostname1) == NULL) {
  251.     // hostname1 is a not substring of hostname2
  252.     // this is done for the case where the playlist has two urls that basically point to the same site
  253.     // one of the sites is an internal URL and the other is an external. We want to be able to play either
  254.     // site. So as long as the hostnames are completly different we should be ok. 
  255.     if (DEBUG > 1)
  256. printf("URLcmp: hostnames do not matchn");
  257.     ret = -1;
  258. } else {
  259.     // url1 is a substring of url2, so continue comparing
  260.     if (DEBUG > 1)
  261. printf("hostname1 = %snhostname2 = %sn", hostname1,
  262.        hostname2);
  263.     // compare the paths, some sites change the hostname mid stream (like cartoonnetwork.com -> www.cartoonnetwork.com);
  264.     tmp1 = strstr(buffer1, "://");
  265.     if (tmp1 != NULL) {
  266. protocol1 =
  267.     (char *) malloc((long) tmp1 - (long) buffer1 + 1);
  268. strncpy(protocol1, buffer1,
  269. (long) tmp1 - (long) buffer1 + 1);
  270. protocol1[(long) tmp1 - (long) buffer1] = '';
  271.     }
  272.     if (DEBUG > 1)
  273. printf("protocol1: %sn", protocol1);
  274.     if (tmp1 != NULL) {
  275. tmp1 = tmp1 + 3;
  276. while (tmp1[0] != '/') {
  277.     if (tmp1[0] == '')
  278. break;
  279.     tmp1++;
  280. }
  281.     }
  282.     tmp2 = strstr(buffer2, "://");
  283.     if (tmp2 != NULL) {
  284. protocol2 =
  285.     (char *) malloc((long) tmp2 - (long) buffer2 + 1);
  286. strncpy(protocol2, buffer2,
  287. (long) tmp2 - (long) buffer2 + 1);
  288. protocol2[(long) tmp2 - (long) buffer2] = '';
  289.     }
  290.     if (DEBUG > 1)
  291. printf("protocol2: %sn", protocol2);
  292.     if (tmp2 != NULL) {
  293. tmp2 = tmp2 + 3;
  294. while (tmp2[0] != '/') {
  295.     if (tmp2[0] == '')
  296. break;
  297.     tmp2++;
  298. }
  299.     }
  300.     if (tmp1 != NULL && tmp2 != NULL) {
  301. if (strcmp(tmp1, tmp2) == 0) {
  302.     // if either protocol is file:// then they are the same at this point usually one will be NULL and the other file://
  303.     if ((strncmp(protocol1, "file://", 7) == 0)
  304. || (strncmp(protocol2, "file://", 7) == 0)) {
  305. ret = 0;
  306.     } else {
  307. // NetFlix puts out the same preview on multiple protocols, we have to add them all to the playlist
  308. if (strcmp(protocol1, protocol2) == 0) {
  309.     ret = 0;
  310. } else {
  311.     ret = -1;
  312. }
  313.     }
  314. } else {
  315.     ret = -1;
  316.     q1 = strchr(tmp1, '?');
  317.     q2 = strchr(tmp2, '?');
  318.     if (q1 != NULL || q2 != NULL) {
  319. if (q1 != NULL) {
  320.     q1[0] = '';
  321.     tmp1hasq = 1;
  322. }
  323. if (q2 != NULL) {
  324.     q2[0] = '';
  325.     tmp2hasq = 1;
  326. }
  327. if (strcmp(tmp1, tmp2) == 0) {
  328.     if (tmp1hasq != tmp2hasq) {
  329. ret = -1;
  330.     } else {
  331. if (strcmp(q1 + 1, q2 + 1) == 0) {
  332.     ret = 0;
  333. } else {
  334.     ret = -1;
  335. }
  336.     }
  337. } else {
  338.     ret = -1;
  339. }
  340.     }
  341. }
  342.     }
  343. }
  344. free(buffer1);
  345. free(buffer2);
  346.     }
  347.     if (hostname1 != NULL)
  348. NPN_MemFree(hostname1);
  349.     if (hostname2 != NULL)
  350. NPN_MemFree(hostname2);
  351.     if (protocol1 != NULL)
  352. free(protocol1);
  353.     if (protocol2 != NULL)
  354. free(protocol2);
  355.     if (DEBUG > 1)
  356. printf("exiting URLcmpn");
  357.     return ret;
  358. }
  359. // Remove all single quotes from url to prevent remote execution
  360. void remove_quotes(char *url)
  361. {
  362.     char *p;
  363.     if (DEBUG > 1)
  364. printf("in remove_quotesn");
  365.     // don't scan the string if it not in there, this should be a bit faster than the while loop
  366.     if (url == NULL)
  367. return;
  368.     p = strchr(url, '`');
  369.     if (p == NULL) {
  370. return;
  371.     } else {
  372. if (DEBUG) {
  373.     printf("single quotes in url (%s), truncatingn"
  374.    "WARNING: probably won't work! FIXME!n", url);
  375. }
  376. *p = '';
  377.     }
  378. }
  379. //  sendCommand is safe to use only with control_mutex held
  380. //  (and in player thread surounded by cleanup_push/cleanup_pop)
  381. // command will be ignored if js_state is JS_STATE_TRANSITIONING
  382. // in cleanup routines (like destroyCB and shut), when we know that
  383. // the player thread is not running, it is safe to call without locking
  384. int sendCommand(nsPluginInstance * instance, char *command)
  385. {
  386.     int retval;
  387.     char buffer[1024];
  388.     if (DEBUG > 1)
  389. printf("in sendcommand - command %sn", command);
  390.     buffer[1023] = '';
  391.     retval = 0;
  392.     if (command == NULL || instance == NULL || instance->cancelled == 1)
  393. return 0;
  394.     if (instance->threadsignaled == 0)
  395. return 0;
  396.     if (instance->control == -1)
  397. return 0;
  398.     if (instance->js_state != JS_STATE_TRANSITIONING) {
  399. snprintf(buffer, 1023, "%sn", command);
  400. retval = write(instance->control, buffer, strlen(buffer));
  401. //operations on pipes are atomic
  402. if (retval < (int) strlen(buffer)) {
  403.     if (DEBUG)
  404. printf("*****sendCommand Truncated*****n");
  405. }
  406.     }
  407.     return retval;
  408. }
  409. void killdownload(nsPluginInstance * instance)
  410. {
  411.     void *thread_return;
  412.     int count, status;
  413.     if (DEBUG > 1)
  414. printf("in killdownloadn");
  415.     if (instance->paused == 1)
  416. sendCommand(instance, "pausen");
  417.     sendCommand(instance, "quitn");
  418.     pthread_mutex_lock(&(instance->read_mutex));
  419.     instance->cancelled = 1;
  420.     pthread_mutex_unlock(&(instance->read_mutex));
  421. /*    count = 0;
  422.     while (count < 500) {
  423. if (DEBUG)
  424.     printf("waiting for quit to be handledn");
  425. usleep(100);
  426. count++;
  427.      if (instance->player == NULL)
  428.     break;
  429.     }
  430. */
  431.     //we can do the following twice on the same thread with no ill effects
  432.     pthread_cancel(instance->player_thread);
  433.     pthread_join(instance->player_thread, &thread_return);
  434.     instance->js_state = JS_STATE_UNDEFINED;
  435.     if (DEBUG)
  436. printf
  437.     ("Trying to kill download process(%d), if it still existsn",
  438.      instance->pid);
  439.     count = 0;
  440.     while (instance->player != NULL && count < 10) {
  441. if (DEBUG)
  442.     printf("waiting for player to go NULLn");
  443. usleep(100);
  444. count++;
  445.     }
  446.     if (instance->player == NULL) {
  447. instance->pid = 0;
  448.     } else {
  449. if (DEBUG > 1)
  450.     printf("closing playern");
  451. //      fclose(instance->player);
  452. instance->player = NULL;
  453. if (DEBUG > 1)
  454.     printf("closing control pipen");
  455. if (instance->control > 0) {
  456.     close(instance->control);
  457.     instance->control = -1;
  458. }
  459.     }
  460.     if (DEBUG > 1)
  461. printf("player should be closedn");
  462.     if (instance->pid != 0) {
  463. count = 0;
  464. status = 1;
  465. while ((status != 0) && (count < 10)) {
  466.     status = kill(instance->pid, 15);
  467.     if (DEBUG)
  468. printf("kill(15) status = %in", status);
  469.     if (status == -1) {
  470. if (errno == ESRCH) {
  471.     status = 0;
  472.     break;
  473. }
  474. usleep(100);
  475.     }
  476.     count++;
  477. }
  478. if (status != 0) {
  479.     status = kill(instance->pid, 9);
  480.     if (DEBUG)
  481. printf("kill(9) status = %in", status);
  482.     if (status == 0) {
  483. instance->pid = 0;
  484.     }
  485. }
  486. //wait(&status);
  487.     }
  488. #ifdef DPMSExtension
  489.     if (instance->DPMSEnabled)
  490. DPMSReenable(instance);
  491. #endif
  492.     if (instance->threadsetup == 1) {
  493. count = 0;
  494. while (count < 50) {
  495.     if (instance->td->argv[count] != NULL)
  496. free(instance->td->argv[count]);
  497.     instance->td->argv[count++] = NULL;
  498. }
  499. instance->threadsetup = 0;
  500. #ifdef GTK_ENABLED
  501. //      if (GTK_IS_WIDGET(instance->drawing_area)) {
  502. //          gtk_widget_destroy(instance->drawing_area);
  503. //          instance->drawing_area = NULL;
  504. //      }
  505. #endif
  506.     }
  507. }
  508. void fullyQualifyURL(nsPluginInstance * instance, char *initem,
  509.      char *localitem)
  510. {
  511.     char tmpdir[1024];
  512.     char *tmp;
  513.     char * item;
  514.     if (DEBUG > 1)
  515. printf("in fullyQualifyURLn");
  516.     
  517.     item = strdup(initem);
  518.     tmp = strstr(item, "<");
  519.     if (tmp != NULL) {
  520. strlcpy(item,tmp+1,1024);
  521. tmp = strstr(item, ">");
  522. if (DEBUG > 1)
  523.     printf("item = %p tmp = %p   diff = %in",item,tmp, (tmp-item));
  524. if (tmp != NULL) {
  525. strlcpy(tmp,"",1024);
  526. }
  527. if (DEBUG > 1)
  528.     printf("item = %sn",item);
  529.     }
  530.     
  531.       if (DEBUG > 1)
  532. printf("item: %snbaseurl: %snhostname: %sn",
  533.        item, instance->baseurl, instance->hostname);
  534.   
  535.     if (!isMms(item, instance->nomediacache)) {
  536. if ((strncasecmp(item, "http", 4) != 0)
  537.     && (strncasecmp(item, "file", 4) != 0)) {
  538.     if (DEBUG > 1)
  539. printf("not http and not filen");
  540.     if (item[0] != '/') {
  541. strlcpy(tmpdir, item, 1024); // reuse the buffer
  542. if (instance->baseurl != NULL) {
  543.     strlcpy(localitem, instance->baseurl, 1024);
  544. } else {
  545.     strlcpy(localitem, "", 1024);
  546. }
  547. strlcat(localitem, tmpdir, 1024);
  548.     } else {
  549. if (instance->hostname != NULL) {
  550.     if (fexists(item) == 0) {
  551. snprintf(tmpdir, 1024, "http://%s%s",
  552.  instance->hostname, item);
  553. strlcpy(localitem, tmpdir, 1024);
  554.     } else {
  555. // first char == / and hostname is null, sounds like a filename
  556. strlcpy(localitem, item, 1024);
  557.     }
  558. } else {
  559.     // first char == / and hostname is null, sounds like a filename
  560.     strlcpy(localitem, item, 1024);
  561. }
  562.     }
  563. } else {
  564.     // if :80 is in the URL, cut it out
  565.     strlcpy(localitem, item, 1024);
  566.     tmp = strstr(localitem, ":8080");
  567.     if (tmp == NULL) {
  568. tmp = strstr(localitem, ":80/");
  569. if (tmp != NULL) {
  570.     *tmp = '';
  571.     strlcat(localitem, tmp + 3, 1024);
  572. }
  573.     }
  574.     if (strncasecmp(localitem, "file://", 7) == 0) {
  575. // chop off file://
  576. strlcpy(tmpdir, localitem, 1024);
  577. strlcpy(localitem, tmpdir + 7, 1024);
  578. // replace %20's in url with a space
  579. if (strstr(localitem, "%20") != NULL) {
  580.     while ((tmp = strstr(localitem, "%20"))) {
  581. if (tmp != NULL) {
  582.     *tmp = ' ';
  583.     tmp++;
  584.     *tmp = '';
  585.     strcat(localitem, tmp + 2);
  586. }
  587.     }
  588. }
  589. // check and see if the file exists, if it does not then prepend smb:// to the filename
  590. if (fexists(localitem) == 0) {
  591.     strlcpy(tmpdir, "smb://", 1024);
  592.     strlcat(tmpdir, localitem, 1024);
  593.     strlcpy(localitem, tmpdir, 1024);
  594. }
  595.     }
  596. }
  597.     } else {
  598. strlcpy(localitem, item, 1024);
  599.     }
  600.     free(item);
  601.     if (DEBUG > 1)
  602. printf("fqu result: %sn", localitem);
  603.     
  604. }
  605. int toolkitOk(NPP instance, int *mozilla_toolkit, int *plugin_toolkit)
  606. {
  607. #ifdef X_ENABLED
  608.     *plugin_toolkit = 0;
  609. #endif
  610. #ifdef GTK1_ENABLED
  611.     *plugin_toolkit = 1;
  612. #endif
  613. #ifdef GTK2_ENABLED
  614.     *plugin_toolkit = 2;
  615. #endif
  616.     if (DEBUG)
  617. printf("checking toolkitn");
  618.     NPN_GetValue(instance, NPNVToolkit, mozilla_toolkit);
  619.     if (DEBUG)
  620. printf("toolkitOk? mozilla = %i, plugin = %in", *mozilla_toolkit,
  621.        *plugin_toolkit);
  622. #ifdef OO_GTK2_ENABLED
  623.     // this is an openoffice workaround, but it does not seem to work.
  624.     if (*mozilla_toolkit == 0) {
  625. if (DEBUG)
  626.     printf("initializing GDK/GTKn");
  627. //g_type_init();
  628. //gdk_init(NULL,NULL);
  629. gtk_init(NULL, NULL);
  630. gtk_main();
  631.     }
  632. #endif
  633.     if (*mozilla_toolkit == 0 || *mozilla_toolkit == 1
  634. || *mozilla_toolkit == 2) {
  635. if (*plugin_toolkit == 0 || *mozilla_toolkit == 0
  636.     || (*mozilla_toolkit == *plugin_toolkit))
  637.     return 0;
  638. else
  639.     return 1;
  640.     } else {
  641. printf("Unknown Mozilla toolkit (%i), assuming toolkit is GTK%in",
  642.        *mozilla_toolkit, *plugin_toolkit);
  643. printf
  644.     ("This may cause Mozilla to crash. If it crashes recompile downloadplug-in with a different toolkit.n");
  645. return 0;
  646.     }
  647. }
  648. #ifdef DPMSExtension
  649. int DPMSIsEnabled(nsPluginInstance * instance)
  650. {
  651.     int dummy;
  652.     BOOL onoff;
  653.     CARD16 state;
  654.     if (DEBUG > 1)
  655. printf("Checking if DPMS is enabledn");
  656.     if (DPMSQueryExtension(instance->display, &dummy, &dummy)) {
  657. if (DPMSCapable(instance->display))
  658.     DPMSInfo(instance->display, &state, &onoff);
  659.     }
  660.     if (DEBUG > 1)
  661. printf("DPMS is enabled = %in", onoff);
  662.     return onoff;
  663. }
  664. void DPMSReenable(nsPluginInstance * instance)
  665. {
  666.     int dummy;
  667.     if (DEBUG > 1)
  668. printf("DPMS is enabledn");
  669.     if (DPMSQueryExtension(instance->display, &dummy, &dummy)) {
  670. if (DPMSCapable(instance->display))
  671.     DPMSEnable(instance->display);
  672.     }
  673. }
  674. #endif